Solución de problemas · Hetzner

¿Tu cron job no funciona en Hetzner? Así se soluciona

Lista de comprobación práctica para cron jobs que no se ejecutan en un servidor Hetzner Cloud o dedicado — entorno, rutas, zona horaria y correo.

Si un cron job funciona cuando lo ejecutas a mano pero nunca se dispara desde crontab en tu servidor Hetzner, casi siempre es una de pocas causas. Recorre esta lista en orden.

1. Confirma que cron está realmente ejecutándose

En una imagen fresca de Hetzner Cloud, el demonio cron debería estar activo — pero verifícalo:

systemctl status cron      # Debian/Ubuntu
systemctl status crond     # CentOS/Rocky/Alma

Si está inactivo, actívalo e inícialo:

sudo systemctl enable --now cron

2. Comprueba que el job está en el crontab correcto

Un job en tu crontab de usuario (crontab -e) se ejecuta como tú; un job en /etc/crontab o /etc/cron.d/* debe incluir un campo de usuario. Editar el equivocado es el error más común:

crontab -l            # jobs de tu usuario
sudo crontab -l       # jobs de root
cat /etc/cron.d/*     # jobs del sistema (necesitan columna de usuario)

3. El PATH es mínimo bajo cron

Cron se ejecuta con un entorno reducido — típicamente PATH=/usr/bin:/bin. Un script que llame a node, python3, docker o pg_dump fallará con “command not found” aunque funcione en tu shell. Usa rutas absolutas, o define PATH al inicio del crontab:

PATH=/usr/local/bin:/usr/bin:/bin
0 2 * * * /usr/local/bin/node /opt/app/job.js

4. Faltan las variables de entorno

Cron no carga ~/.bashrc, ~/.profile ni /etc/environment como lo hace un login interactivo. Los secretos y la configuración de los que dependes simplemente no están disponibles. Cárgalos explícitamente:

0 2 * * * . /opt/app/.env && /opt/app/run.sh

5. Comprueba la zona horaria del servidor

Las imágenes de Hetzner suelen venir en UTC por defecto. 0 9 * * * se dispara entonces a las 09:00 UTC, no a las 09:00 de tu hora local. Compruébalo y, si hace falta, cámbialo:

timedatectl                       # ver la zona horaria actual
sudo timedatectl set-timezone Europe/Berlin

6. Lee los logs

Cron registra cada ejecución. Si no ves tu job, es que no está coincidiendo:

grep CRON /var/log/syslog         # Debian/Ubuntu
journalctl -u cron --since today

Si no aparece ninguna línea en el log, lo más probable es que haya una expresión de planificación incorrecta o que estés mirando el crontab equivocado.

El problema más profundo: solo te diste cuenta porque fuiste a mirar

Todas las soluciones anteriores asumen que fuiste a buscar. El job que dejó de funcionar silenciosamente hace seis semanas es el que duele. Cron no tiene ningún concepto de éxito o fallo y no te avisa cuando para.

Añade un heartbeat: haz que el job haga ping a una URL cuando termine, y recibe una alerta en el momento en que se pierda un ping. Una sola línea al final de tu script:

curl -fsS https://ping.steadycron.com/<tu-ping-token>