Insights de dominios

Cron para principiantes: programa copias de seguridad, scripts y tareas en tu VPS

Interpreta crontab, programa scripts probados, protege copias de bases de datos, registra errores y resuelve fallos de cron en un VPS Linux.

Linux y VPS
Cron para principiantes: programa copias de seguridad, scripts y tareas en tu VPS

Tienes un script que funciona. Cada noche entras al VPS, lo ejecutas, esperas y cierras la conexión. Quizá exporta una base de datos, prepara un informe o realiza mantenimiento.

Después de repetirlo varios días, resulta evidente que el servidor debería hacerlo por su cuenta. Cron permite programar comandos para que se ejecuten automáticamente, aunque no estés conectado.

La idea es sencilla: defines un comando y un horario. Esta guía explica la sintaxis, prepara una primera tarea y te ayuda a investigar cuando parece que no ocurrió nada.

Qué es una tarea cron

Una tarea cron combina un comando con un calendario de ejecución. Por ejemplo, en vez de invocar cada noche un script como este:

/home/soxdomains/scripts/backup.sh

Cron lee archivos de programación llamados crontabs y ejecuta los comandos que coinciden con el horario. Tu usuario no necesita mantener una sesión SSH abierta.

Abre tu crontab personal

Para editar las tareas de tu usuario:

crontab -e

La primera vez puede pedirte elegir un editor. Si estás empezando, nano suele resultar más sencillo que vim. Consulta las tareas actuales con:

crontab -l

Para editar las tareas de root:

sudo crontab -e

No uses root solo porque una ejecución falló con tu usuario. Elige la identidad menos privilegiada que pueda realizar el trabajo.

Los cinco campos del horario

Una entrada de tu crontab personal tiene cinco campos y después el comando:

* * * * * command
PosiciónCampoValores habituales
1Minuto0 a 59
2Hora0 a 23
3Día del mes1 a 31
4Mes1 a 12
5Día de la semana0 a 7

El domingo suele representarse con 0 o 7. Un asterisco indica todos los valores admitidos. Esta entrada ejecuta un script cada minuto:

* * * * * /home/soxdomains/test.sh

Es útil para una prueba corta. Retírala cuando termines. Los crontabs del sistema, como /etc/crontab, tienen además un campo de usuario; no copies ese formato en tu crontab personal.

Si restringes tanto el día del mes como el día de la semana, el cron tradicional ejecuta la tarea cuando coincide cualquiera de esos dos campos, siempre que coincidan los demás. No presupongas que exige ambos a la vez.

Horarios útiles

Cada día a las 2:00:

0 2 * * * /home/soxdomains/scripts/backup.sh

Cada hora, en el minuto 15:

15 * * * * /home/soxdomains/scripts/task.sh

Cada lunes a las 7:30:

30 7 * * 1 /home/soxdomains/scripts/report.sh

El primer día de cada mes a medianoche:

0 0 1 * * /home/soxdomains/scripts/monthly.sh

Cada quince minutos:

*/15 * * * * /home/soxdomains/scripts/check.sh

Cada día a las 23:45:

45 23 * * * /home/soxdomains/scripts/task.sh

La expresión 30 4 * * 0 corresponde al domingo a las 4:30. Lee siempre de izquierda a derecha: minuto, hora, día del mes, mes y día de la semana.

Tu primera tarea cron

Crea una carpeta para los scripts y abre un archivo de prueba:

mkdir -p ~/scripts
nano ~/scripts/hello-cron.sh

Añade este contenido y reemplaza /home/soxdomains por tu directorio real:

#!/bin/bash
date >> /home/soxdomains/cron-test.log
echo "Cron ran successfully" >> /home/soxdomains/cron-test.log

Dale ejecución al propietario y pruébalo manualmente:

chmod u+x ~/scripts/hello-cron.sh
~/scripts/hello-cron.sh
cat ~/cron-test.log

Después abre crontab -e y añade temporalmente:

* * * * * /home/soxdomains/scripts/hello-cron.sh

Espera uno o dos minutos y consulta el registro. Cuando compruebes que funciona, elimina la programación de prueba.

Ejemplo de copia de MySQL

Para una base llamada exampleapp, este script prepara un archivo temporal y solo publica el nombre final si el volcado termina correctamente:

#!/bin/bash
set -eu
umask 077
BACKUP_DIR="/home/soxdomains/backups"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
mkdir -p "$BACKUP_DIR"
TEMP_FILE=$(mktemp "$BACKUP_DIR/exampleapp_$DATE.XXXXXX.part")
trap 'rm -f -- "$TEMP_FILE"' EXIT
/usr/bin/mysqldump --single-transaction --no-tablespaces exampleapp > "$TEMP_FILE"
test -s "$TEMP_FILE"
mv "$TEMP_FILE" "$BACKUP_DIR/exampleapp_$DATE.sql"

Guárdalo como /home/soxdomains/scripts/mysql-backup.sh, verifica las rutas y restringe su acceso:

chmod 700 /home/soxdomains/scripts/mysql-backup.sh

Pruébalo manualmente antes de añadir esta entrada:

0 2 * * * /home/soxdomains/scripts/mysql-backup.sh

set -eu detiene el script ante errores o variables no definidas. umask 077 restringe los nuevos archivos y directorios al propietario; no cambia los permisos de objetos que ya existen. Revisa también el directorio de copias existente.

--single-transaction permite un volcado consistente de tablas transaccionales como InnoDB, con limitaciones. No garantiza lo mismo para MyISAM y los cambios de estructura durante el volcado pueden invalidarlo. --no-tablespaces omite sentencias de tablespaces. Los permisos necesarios, rutinas, eventos y ajustes GTID dependen de tu base y del plan de restauración.

Configura un método de autenticación que funcione sin interacción para el usuario de cron. Evita exponer una contraseña en la línea de comandos y restringe los archivos de credenciales. Una copia guardada solo en el mismo VPS no protege frente a perder todo el servidor.

Cron tiene un entorno más pequeño

Un comando puede funcionar en tu terminal y fallar en cron porque su entorno y su PATH son distintos. Localiza el ejecutable:

command -v mysqldump

Si devuelve /usr/bin/mysqldump, usa esa ruta en el script. Aplica lo mismo a PHP, Python, Node.js, Composer y tus programas. Define de forma explícita las variables necesarias.

Usa rutas absolutas

Este comando depende del directorio de trabajo:

cp config.php backups/

Cron puede empezar en otro lugar. Es más claro indicar las rutas completas:

cp /var/www/example.com/config.php /home/soxdomains/backups/

Si una aplicación requiere un directorio de trabajo concreto, entra explícitamente en él dentro del script y comprueba que la operación tuvo éxito.

Registra la salida y los errores

Crea primero el directorio de registros:

mkdir -p /home/soxdomains/logs

Una programación con registro puede ser:

0 2 * * * /home/soxdomains/scripts/backup.sh >> /home/soxdomais/logs/backup.log 2>&1

>> añade salida al archivo y 2>&1 envía los errores al mismo destino. Consulta las últimas líneas:

tail -n 100 /home/soxdomains/logs/backup.log

Protege los registros que contienen datos sensibles y define una rotación para evitar que crezcan indefinidamente.

¿Falló cron o falló el comando?

En Ubuntu, una consulta útil es:

sudo journalctl -u cron --since "1 hour ago"

Los registros disponibles dependen del servicio y de su configuración; también pueden aparecer en syslog. Si cron lanzó el comando, la programación puede estar funcionando y el fallo estar dentro del script.

Primero confirma que hubo una ejecución. Después investiga la tarea con su salida, sus errores y su código de retorno.

Problemas de permisos

Si aparece Permission denied, consulta el script y comprueba su ejecución:

ls -l /home/soxdomains/scripts/backup.sh
chmod u+x /home/soxdomains/scripts/backup.sh

El usuario de cron también debe poder leer los datos de origen y escribir en el destino. No conviertas toda la web a 777. Consulta la guía de permisos de Linux.

La identidad de ejecución importa

Una tarea creada con crontab -e se ejecuta como tu usuario. Una creada con sudo crontab -e usa root. Eso cambia la propiedad de archivos, el directorio personal, las claves SSH y las credenciales disponibles.

Elige la identidad deliberadamente. Un respaldo creado por root puede resultar difícil de administrar después desde la cuenta de la aplicación.

Versiones de PHP y Python

Selecciona el ejecutable que realmente necesita la aplicación:

*/5 * * * * /usr/bin/php /var/www/example.com/cron.php >> /home/soxdomains/logs/app-cron.log 2>&1
0 * * * * /usr/bin/python3 /home/soxdomains/scripts/report.py

Las rutas son ejemplos. Para Python con entorno virtual, normalmente puedes invocar directamente su intérprete, como /home/soxdomains/venv/bin/python. Cron no reproduce automáticamente lo que activas en una sesión interactiva.

Evita concentrarlo todo a medianoche

Varias copias, compresiones y análisis iniciados a la vez pueden elevar el uso de CPU y disco. Distribuye los horarios según la duración y las dependencias:

5 0 * * *
20 0 * * *
45 0 * * *
15 1 * * *

También evita que una tarea nueva empiece antes de terminar la anterior. En sistemas con flock, puedes usar un bloqueo:

0 2 * * * /usr/bin/flock -n /home/soxdomains/backups/mysql-backup.lock /home/soxdomains/scripts/mysql-backup.sh >> /home/soxdomains/logs/backup.log 2>&1

Esta entrada reemplaza la programación sin bloqueo del mismo respaldo. No la añadas como una segunda copia de la tarea. Crea las carpetas antes, verifica la ruta de flock y vigila las ejecuciones omitidas: -n sale inmediatamente si otra ejecución mantiene el bloqueo.

La retención importa

Una tarea de respaldo puede llenar el disco si conserva todos los archivos. Antes de diseñar una política de eliminación, consulta los archivos que coincidirían:

find /home/soxdomains/backups -type f -name "*.sql" -mtime +14 -print

El comando solo muestra resultados. Revisa cuidadosamente qué copias necesitas conservar y confirma que existen copias externas recuperables antes de automatizar eliminaciones.

Comprueba la zona horaria

Cron usa normalmente la zona configurada en el servidor:

timedatectl

Si el VPS usa UTC, las 8:00 del crontab no equivalen necesariamente a las 8:00 de tu ciudad. Documenta la zona prevista para informes, facturación, copias y avisos.

Algunas implementaciones permiten CRON_TZ; comprueba la tuya antes de usarlo. Los cambios de horario estacional pueden omitir o repetir horas locales, y el tratamiento depende del programador. Consulta su documentación para tareas donde eso importe.

Cron desde cPanel

Si la función está habilitada, Cron Jobs permite elegir horarios comunes o completar los campos manualmente. Una tarea PHP podría usar:

/usr/local/bin/php /home/username/public_html/task.php

Verifica el binario y la versión en tu alojamiento. No copies una ruta de otro proveedor sin comprobarla. Durante la configuración, recibir la salida por correo puede ayudarte a detectar errores.

Consulta también tu primera hora en cPanel.

Comprueba que la copia se puede recuperar

Encontrar un archivo SQL nuevo no demuestra que el respaldo sea válido. Revisa periódicamente:

  1. Que el archivo exista.
  2. Que su tamaño sea razonable.
  3. Que no esté vacío.
  4. Que pueda leerse.
  5. Que el comando haya terminado correctamente.
  6. Que una restauración de prueba funcione.
  7. Que exista una copia fuera del VPS.

Un proceso automático también puede repetir errores todos los días. La restauración de prueba comprueba el resultado que realmente necesitas.

Lista de diagnóstico

  1. Ejecuta el comando manualmente con la identidad correcta.
  2. Confirma los permisos de ejecución del script.
  3. Usa rutas absolutas.
  4. Comprueba el usuario propietario del crontab.
  5. Revisa el acceso a archivos y carpetas.
  6. Registra salida y errores.
  7. Consulta los registros de cron.
  8. Verifica la zona horaria.
  9. Define las variables necesarias.
  10. Comprueba las rutas de los ejecutables.
  11. Revisa espacio libre con df -h.
  12. Usa un horario frecuente solo para una prueba temporal y retíralo después.

Continúa con tu servidor

Para configurar el acceso, consulta SSH para principiantes. Si buscas alojamiento para tus aplicaciones y tareas programadas, revisa nuestras opciones VPS.

Más respuestas prácticas

¿Cómo edito mis tareas?

Usa crontab -e para editar las tareas de tu usuario.

¿Cómo consulto mis tareas?

Usa crontab -l para ver las entradas existentes.

¿Debo mantener mi ordenador conectado?

No. La tarea se ejecuta en el servidor y continúa aunque cierres tu sesión.

¿Puedo programar respaldos de bases de datos?

Sí. Programa un script probado, conserva copias protegidas fuera del VPS y verifica una restauración.

Preguntas frecuentes

¿Qué es cron?

Es un programador utilizado en sistemas Linux para ejecutar comandos automáticamente en los horarios que defines.

¿Qué significa 0 2 *?

Programa una ejecución diaria a las 2:00 según la zona horaria que utiliza cron en el servidor.

¿Por qué funciona por SSH pero falla en cron?

Cron puede usar un entorno y un PATH distintos. Indica rutas absolutas, define las variables necesarias y registra los errores.

¿Debo ejecutar todo como root?

No. Usa la cuenta con menos privilegios que pueda completar el trabajo.