[{"data":1,"prerenderedAt":218},["ShallowReactive",2],{"seo-verification":3,"blog-cron-vs-systemd-timers-automatizar-vps-linux-ma-es":6,"promo-bar-likely":217},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-cron-vs-systemd-timers-automatizar-vps-linux-ma-es",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":29,"intro":32,"sections":33,"ctaTitle":161,"ctaBody":162,"ctaButton":163,"ctaUrl":164,"relatedPosts":165},230,"cron-vs-systemd-timers-automatizar-vps-linux",{"fr":12,"en":13,"ar":14,"es":10},"cron-systemd-timers-automatisation-vps","cron-vs-systemd-timers-automate-your-linux-vps","cron-مقابل-systemd-timers-أتمتة-vps-linux","cron vs systemd timers: automatizar su VPS Linux","Comparativa práctica de cron y systemd timers: sintaxis, logs, migración y solución de problemas para sus tareas recurrentes en un VPS Linux.",12,1,false,"2026-08-06T00:00:00+00:00","2026-09-20T21:13:53+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},2,"Automatización","automatisation","bg-brand-action\u002F10 text-brand-action",[28],{"id":23,"name":24,"slug":25,"color":26,"icon":25},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fcron-systemd-timers-automatisation-vps-poster.svg","En un VPS Linux, la automatización no es un lujo: copias de seguridad nocturnas, renovación de certificados TLS, purga de logs, sondas de salud — esas tareas se ejecutan sin usted o no se ejecutan. Cron reina desde hace décadas, pero los systemd timers ofrecen una integración más profunda con el gestor de servicios. Esta guía compara ambas herramientas, describe cuándo elegir una u otra y le acompaña paso a paso para crear o migrar un timer de systemd.",[34,38,49,52,55,99,102,105,133,151,155,158],{"type":35,"title":36,"body":37},"h2","¿Por qué automatizar las tareas en un VPS?","Un VPS es un servidor que funciona de forma continua, a menudo sin supervisión humana directa. Precisamente por eso la automatización de las tareas recurrentes es fundamental: nadie estará ahí a las 3 de la madrugada para lanzar la copia de seguridad o renovar el certificado Let's Encrypt. Una tarea olvidada puede traducirse en una pérdida de datos, en un certificado caducado que deja el sitio fuera de línea o en un disco saturado por falta de rotación de logs.\n\nEn la práctica, cinco categorías de tareas aparecen en todo VPS Linux serio: **rotación de logs de Nginx** para evitar que `\u002Fvar\u002Flog\u002Fnginx\u002F` llegue a varios gigabytes en pocas semanas; **limpieza de imágenes Docker** huérfanas (`docker image prune -af`) para recuperar espacio en disco sin intervención manual; **copias de seguridad de PostgreSQL** hacia almacenamiento remoto; **verificación del certificado SSL** antes de su expiración para lanzar una renovación de certbot; y finalmente scripts de **scraping ligero o indexación** planificados que deben ejecutarse a hora fija. Las dos grandes herramientas disponibles en Linux — cron y los systemd timers — permiten planificar estas operaciones de forma fiable.",{"type":39,"title":40,"items":41},"ul","Casos de uso típicos en un VPS",[42,43,44,45,46,47,48],"**Copias de seguridad** — dump de MySQL o PostgreSQL a almacenamiento remoto (`pg_dump -Fc mydb | gzip > \u002Fbackup\u002Fmydb_$(date +%F).sql.gz`), archivado de ficheros con `rsync` o `rclone` hacia un bucket S3","**Renovación de certificados TLS** — `certbot renew --quiet` o `acme.sh --cron` planificados dos veces al día, con recarga automática de Nginx tras el éxito","**Rotación y purga de logs** — borrado de los ficheros de más de 30 días (`find \u002Fvar\u002Flog -mtime +30 -delete`), compresión semanal, vaciado de logs de aplicación en producción","**Limpieza de Docker** — `docker image prune -af`, eliminación de volúmenes huérfanos, rotación de logs de contenedores para liberar `\u002Fvar\u002Flib\u002Fdocker`","**Sondas de salud** — comprobación de que un servicio escucha (`curl -sf http:\u002F\u002Flocalhost:3000\u002Fhealth`), reinicio automático si hace falta, alerta por webhook","**Sincronización de datos** — `rsync` hacia un segundo nodo, actualización de cachés, sincronización de ficheros estáticos hacia un CDN","**Tareas de aplicación planificadas** — envío de correos recordatorios, cálculo de informes periódicos, indexación de contenido, scripts de scraping ligero",{"type":35,"title":50,"body":51},"cron: recordatorio rápido","Cron está presente en casi todos los sistemas Linux. Para planificar una tarea se edita la crontab del usuario actual con `crontab -e`. La sintaxis se basa en **cinco campos** separados por espacios, seguidos del comando:\n\n```\n# minuto (0-59), hora (0-23), día del mes (1-31), mes (1-12), día de la semana (0-7)\n  0  3  *  *  *  \u002Fusr\u002Flocal\u002Fbin\u002Fbackup.sh\n```\n\nLos atajos `@daily`, `@weekly`, `@monthly` y `@reboot` simplifican los casos habituales. Los ficheros en `\u002Fetc\u002Fcron.d\u002F` pertenecen al sistema e indican el usuario de ejecución directamente. Para revisar las ejecuciones pasadas: `\u002Fvar\u002Flog\u002Fsyslog` con `grep CRON \u002Fvar\u002Flog\u002Fsyslog`, o `journalctl -t CRON`. Un detalle importante: el `PATH` por defecto de cron es **mínimo** — `\u002Fusr\u002Fbin:\u002Fbin` — lo que obliga a usar rutas absolutas en los scripts, o a redefinir `PATH=` al inicio de la crontab. La variable `MAILTO` controla el envío de salidas por correo; ponerla vacía (`MAILTO=\"\"`) lo desactiva silenciosamente. Cron no conserva ningún historial nativo de las ejecuciones pasadas y no gestiona las tareas perdidas si la máquina estaba apagada.",{"type":35,"title":53,"body":54},"systemd timers: introducción","Un timer de systemd es una pareja de dos ficheros de unidad: un fichero `.service` que describe qué ejecutar y un fichero `.timer` que describe cuándo lanzarlo. El timer se activa con `systemctl enable --now monservice.timer` y lo gobierna el gestor de servicios.\n\nLa directiva `OnCalendar=` acepta una sintaxis rica y legible:\n- `daily` — todos los días a medianoche\n- `Mon *-*-* 03:00:00` — cada lunes a las 3 AM\n- `*-*-* 02:30:00` — todos los días a las 2:30\n- `*:0\u002F15` — cada 15 minutos\n\nLa directiva `AccuracySec=` (por defecto: 1 minuto) permite a systemd agrupar los timers próximos para ahorrar despertares del procesador. La directiva `Persistent=true` en el bloque `[Timer]` es la funcionalidad diferencial respecto a cron: si la máquina estaba apagada a la hora prevista, el timer **recupera la ejecución perdida** en el siguiente arranque. Todas las salidas pasan por journald y se consultan con `journalctl -u monservice.service`. El comando `systemctl list-timers` muestra todos los timers activos, su próximo vencimiento y la fecha de su última activación.",{"type":56,"title":57,"headers":58,"rows":62},"comparison","cron vs systemd timers: tabla comparativa",[59,60,61],"Criterio","cron","systemd timer",[63,67,71,75,79,83,87,91,95],[64,65,66],"Sintaxis de planificación","5 campos `* * * * *`","`OnCalendar=` legible (`daily`, `Mon 03:00`)",[68,69,70],"Logs","Salida por correo o redirección manual, `\u002Fvar\u002Flog\u002Fsyslog`","journald nativo, `journalctl -u`",[72,73,74],"Tareas perdidas (máquina apagada)","Perdidas (salvo `anacron`)","`Persistent=true` las reproduce tras reiniciar",[76,77,78],"Dependencias entre servicios","Ninguna","`After=`, `Requires=`, `Wants=`",[80,81,82],"Aislamiento y recursos","Hereda el entorno del shell, PATH mínimo","Cgroups, `MemoryMax=`, `CPUQuota=`",[84,85,86],"Notificación de fallo","Ninguna de forma nativa","`OnFailure=notify.service` dispara una alerta",[88,89,90],"Ejecución como un usuario concreto","Campo user en `\u002Fetc\u002Fcron.d\u002F`","`User=` y `Group=` en el `.service`",[92,93,94],"Depuración","Difícil sin logs","`systemctl status`, `journalctl -xe`",[96,97,98],"Disponibilidad","Todos los sistemas Unix (contenedores, BSD, Alpine)","Sistemas con systemd (Debian, Ubuntu, RHEL…)",{"type":35,"title":100,"body":101},"¿Cuándo conservar cron?","Cron sigue siendo la buena elección en varias situaciones concretas. En **sistemas antiguos o minimalistas sin systemd** — algunos contenedores Docker ligeros, imágenes Alpine, sistemas BSD — cron suele ser la única herramienta disponible. En un **entorno multiusuario** donde cada desarrollador gestiona sus propias tareas con `crontab -e` sin permisos de root, cron es más sencillo de delegar.\n\nPara **scripts de una sola línea** muy simples — un `certbot renew` semanal, un `rsync` nocturno sin dependencias — la crontab sigue siendo legible y mantenible sin multiplicar los ficheros. Cron es también la buena elección para **incorporar a un equipo no especializado en Linux**: la sintaxis de los cinco campos, documentada en todas partes, es más accesible que una unidad systemd. Por último, si sus tareas cron **llevan años funcionando sin problemas**, la migración no aporta valor inmediato. El criterio decisivo es la necesidad de logs estructurados, dependencias entre servicios o restricciones de recursos.",{"type":35,"title":103,"body":104},"¿Cuándo pasar a los systemd timers?","Los timers de systemd se imponen en cuanto la tarea supera el marco de un simple comando aislado. ¿Necesita **journald** para trazar cada ejecución, sus salidas y su código de retorno sin fontanería manual? Systemd timers. ¿Su script de copia de seguridad debe ejecutarse solo después de que PostgreSQL esté listo, declarando `After=postgresql.service`? Systemd timers. ¿Quiere limitar la memoria de un trabajo de sincronización para que no ahogue a los demás procesos (`MemoryMax=512M`)? Systemd timers.\n\nLas **dependencias entre servicios** son el argumento más fuerte: un backup lanzado cuando la base de datos no está disponible tras un reinicio produce un fichero vacío sin error visible bajo cron. Systemd garantiza el orden. El **logging integrado** via journald elimina todo el ruido de las redirecciones manuales. La **gestión de errores** con `OnFailure=` permite disparar una notificación (correo, webhook) sin contaminar el script. Y si el servidor se reinicia a las 2:58 cuando la copia de las 3 tendría que haberse ejecutado, `Persistent=true` garantiza que se ejecutará en el siguiente arranque.",{"type":106,"title":107,"steps":108},"steps","Crear un timer de systemd desde cero (ejemplo: copia de seguridad diaria)",[109,112,115,118,121,124,127,130],{"title":110,"body":111},"Crear el fichero service","Abra `\u002Fetc\u002Fsystemd\u002Fsystem\u002Fbackup.service` e introduzca:\n\n```ini\n[Unit]\nDescription=Copia de seguridad diaria de PostgreSQL\nAfter=postgresql.service\n\n[Service]\nType=oneshot\nUser=postgres\nExecStart=\u002Fusr\u002Flocal\u002Fbin\u002Fbackup.sh\n```\n\nEl tipo `oneshot` indica que el servicio termina una vez ejecutado el script — el tipo estándar para las tareas planificadas.",{"title":113,"body":114},"Crear el fichero timer","Cree `\u002Fetc\u002Fsystemd\u002Fsystem\u002Fbackup.timer` con:\n\n```ini\n[Unit]\nDescription=Disparador diario de la copia de seguridad\n\n[Timer]\nOnCalendar=*-*-* 03:00:00\nPersistent=true\n\n[Install]\nWantedBy=timers.target\n```\n\n`Persistent=true` garantiza que si la máquina estaba apagada a las 3, la copia se ejecutará en el siguiente arranque.",{"title":116,"body":117},"Recargar systemd y activar el timer","Ejecute `systemctl daemon-reload` para que systemd tenga en cuenta los nuevos ficheros, y luego active e inicie el timer de inmediato:\n\n```bash\nsystemctl enable --now backup.timer\n```",{"title":119,"body":120},"Comprobar con systemctl status","Compruebe el estado del timer con `systemctl status backup.timer` — la salida debe indicar `active (waiting)` y mostrar la próxima fecha de disparo. Consulte también el estado del servicio tras la primera ejecución con `systemctl status backup.service`.",{"title":122,"body":123},"Listar todos los timers activos","El comando `systemctl list-timers --all` muestra una tabla de todos los timers del sistema con tres columnas clave: `NEXT` (próxima ejecución), `LEFT` (tiempo restante) y `LAST` (última ejecución). Es su panel de control para verificar que sus timers se disparan como se espera.",{"title":125,"body":126},"Consultar los logs","Acceda a todas las salidas del servicio con `journalctl -u backup.service` para el historial completo, o `journalctl -u backup.service -n 50 --since today` para las 50 últimas líneas del día.",{"title":128,"body":129},"Añadir notificación de error (opcional)","Para recibir alertas en caso de fallo, añada en el bloque `[Unit]` del fichero `.service`:\n\n```ini\nOnFailure=notify-failure@%n.service\n```\n\nEste servicio puede enviar un correo, un webhook de Slack o un ping ntfy según su infraestructura. Es lo que cron no puede hacer de forma nativa sin fontanería en el propio script.",{"title":131,"body":132},"Probar el servicio manualmente","Antes de esperar el disparo planificado, pruebe la ejecución inmediata con `systemctl start backup.service` (sin `.timer`). Consulte el resultado de inmediato con `journalctl -u backup.service -n 20`. Si el script tiene éxito, la configuración está validada.",{"type":106,"title":134,"steps":135},"Migrar una tarea cron existente a systemd",[136,139,142,145,148],{"title":137,"body":138},"Identificar la tarea cron que migrar","Liste sus crontabs con `crontab -l` (usuario actual) y `cat \u002Fetc\u002Fcron.d\u002F*` (sistema). Anote el comando exacto, el usuario de ejecución y la planificación en cinco campos. Por ejemplo: `30 2 * * 1 root \u002Fusr\u002Fbin\u002Fcertbot renew --quiet` significa cada lunes a las 2:30 como root.",{"title":140,"body":141},"Traducir la planificación a OnCalendar","El formato `OnCalendar=` de systemd se escribe `DayOfWeek Year-Month-Day Hour:Minute:Second`. `30 2 * * 1` se convierte en `Mon *-*-* 02:30:00`.\n\nPara validar la traducción antes de aplicarla, use `systemd-analyze calendar`:\n\n```bash\nsystemd-analyze calendar 'Mon *-*-* 02:30:00'\n```\n\nEl comando muestra las 10 próximas ocurrencias calculadas, eliminando cualquier ambigüedad sobre el comportamiento real.",{"title":143,"body":144},"Crear los ficheros .service y .timer","Cree `\u002Fetc\u002Fsystemd\u002Fsystem\u002Fcertbot-renew.service` con `Type=oneshot`, `ExecStart=\u002Fusr\u002Fbin\u002Fcertbot renew --quiet` y `User=root`. Cree después `\u002Fetc\u002Fsystemd\u002Fsystem\u002Fcertbot-renew.timer` con `OnCalendar=Mon *-*-* 02:30:00` y `Persistent=true`. Ejecute `systemctl daemon-reload && systemctl enable --now certbot-renew.timer`.",{"title":146,"body":147},"Probar el servicio antes de desactivar cron","Pruebe de inmediato con `systemctl start certbot-renew.service` y consulte el resultado con `journalctl -u certbot-renew.service -n 20`. Compruebe que el timer aparece en `systemctl list-timers` con una fecha próxima coherente. **Solo desactive la línea cron tras la validación.**",{"title":149,"body":150},"Desactivar la línea cron","Una vez validado el timer, comente o borre la línea en la crontab original. Para un fichero en `\u002Fetc\u002Fcron.d\u002F`, renómbrelo con extensión `.disabled` o bórrelo. Deje coexistir ambos durante unos días si la tarea es crítica — cron y los systemd timers no interfieren.",{"type":152,"title":153,"body":154},"tip","Validar y depurar sus expresiones OnCalendar","Antes de activar un timer en producción, valide siempre su expresión `OnCalendar=` con `systemd-analyze calendar`:\n\n```bash\nsystemd-analyze calendar \"daily\"\nsystemd-analyze calendar \"Mon *-*-* 02:30:00\"\nsystemd-analyze calendar \"*:0\u002F15\"\n```\n\nCada comando muestra la próxima ocurrencia y las diez siguientes — lo que hace inmediatamente visible una expresión mal formada o un desfase horario inesperado. Para una visión de todos sus timers activos con su próxima fecha de disparo y el tiempo restante, `systemctl list-timers --all` es su panel operacional diario.",{"type":35,"title":156,"body":157},"Problemas frecuentes con los timers de systemd","Cinco problemas se repiten al poner en marcha los timers.\n\n**1. \"Unit not found\" al hacer `systemctl enable`** — el fichero `.timer` o `.service` no está en `\u002Fetc\u002Fsystemd\u002Fsystem\u002F` o tiene un nombre incorrecto. Compruebe la ortografía exacta con `ls \u002Fetc\u002Fsystemd\u002Fsystem\u002F*.timer`. Un `daemon-reload` es obligatorio antes de cualquier `enable` o `start` sobre un fichero nuevo.\n\n**2. Timer activo pero que nunca se dispara** — ¿muestra `systemctl list-timers` una fecha coherente en la columna `NEXT`? Si `NEXT` está vacío o en el pasado, un `Persistent=true` olvidado combinado con una máquina que no ha reiniciado desde la creación del timer es una causa habitual. Compruebe `systemctl status backup.timer`: `active (waiting)` es el estado normal.\n\n**3. ExecStart no encontrado o permiso denegado** — use siempre la **ruta absoluta** en `ExecStart=` (`\u002Fusr\u002Fbin\u002Fcertbot` y no `certbot`). Verifique que el script es ejecutable (`chmod +x \u002Fusr\u002Flocal\u002Fbin\u002Fbackup.sh`) y que el usuario declarado en `User=` tiene acceso a él.\n\n**4. Permisos en el script** — si `User=postgres` pero el script pertenece a root sin permiso de ejecución para postgres, el servicio fallará con el código 203\u002FEXEC. Consulte `journalctl -u backup.service -n 20` para ver el mensaje exacto.\n\n**5. Conflicto entre cron y systemd en la misma tarea** — si está migrando de forma progresiva, asegúrese de no tener ambos activos a la vez para una tarea destructiva (purga de logs, rotación de ficheros). Los dos se ejecutarán independientemente y duplicarán las operaciones. La comprobación es sencilla: `crontab -l | grep backup` y `systemctl is-active backup.timer`.",{"type":35,"title":159,"body":160},"Conclusión","Cron y los systemd timers conviven sin problema en el mismo servidor: no tiene que migrarlo todo de golpe. Conserve cron para sus tareas sencillas y sus scripts de usuario existentes, y adopte los timers de systemd para las nuevas automatizaciones que se benefician de los logs de journald, de las dependencias entre servicios o del aislamiento por cgroups. Los comandos `systemd-analyze calendar` y `systemctl list-timers` son sus mejores aliados para validar y supervisar sus planificaciones.","Un VPS Linux listo para sus automatizaciones","Nuestros VPS cloud con Ubuntu y Debian incluyen systemd, journald y toda la pila moderna. Despliegue sus timers, scripts y copias de seguridad sobre una infraestructura fiable, con acceso root completo y soporte ágil.","Lanzar un VPS Linux","\u002Fvps-cloud",[166,184,199],{"id":167,"slug":168,"slugs":169,"title":173,"excerpt":174,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":175,"updatedAt":176,"category":177,"categories":178,"featuredImage":29,"bgImage":30,"posterImage":180,"relatedSolution":181},31,"instalar-apache-airflow-en-un-vps",{"fr":170,"en":171,"ar":172,"es":168},"installer-apache-airflow-vps","installing-apache-airflow-on-a-vps-self-hosted-automation","تثبيت-apache-airflow-على-خادم-vps-أتمتة-ذاتية-الاستضافة","Instalar Apache Airflow en VPS: Docker Compose y PostgreSQL","Instala Apache Airflow en VPS con Docker Compose: PostgreSQL como backend, CeleryExecutor para escalar y gestión de secretos cifrados.","2026-05-20T00:00:00+00:00","2026-11-04T16:30:25+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[179],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Finstaller-apache-airflow-vps-poster.svg",{"categorySlug":182,"appSlug":183},"automatizacion","airflow",{"id":185,"slug":186,"slugs":187,"title":191,"excerpt":192,"readTime":17,"views":23,"isPinned":19,"noindex":19,"publishedAt":193,"updatedAt":194,"category":195,"categories":196,"featuredImage":29,"bgImage":30,"posterImage":198,"relatedSolution":29},212,"woodpecker-ci-forgejo-pipeline-cicd-vps",{"fr":188,"en":189,"ar":190,"es":186},"woodpecker-ci-pipeline-vps-forgejo","woodpecker-ci-and-forgejo-cicd-pipeline-on-a-vps","woodpecker-ci-وforgejo-خط-أنابيب-cicd-على-خادم-vps","Woodpecker CI y Forgejo: pipeline CI\u002FCD en un VPS","Despliega Woodpecker CI v3 con Forgejo en tu VPS: configuración Docker Compose, pipelines YAML, secretos, runners multi-arquitectura y depuración OAuth.","2026-08-02T00:00:00+00:00","2026-11-08T01:13:13+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[197],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Fwoodpecker-ci-pipeline-vps-forgejo-poster.svg",{"id":200,"slug":201,"slugs":202,"title":206,"excerpt":207,"readTime":208,"views":209,"isPinned":19,"noindex":19,"publishedAt":210,"updatedAt":176,"category":211,"categories":212,"featuredImage":29,"bgImage":30,"posterImage":214,"relatedSolution":215},29,"instalar-kestra-en-un-vps",{"fr":203,"en":204,"ar":205,"es":201},"installer-kestra-vps","installing-kestra-on-a-vps-self-hosted-automation","تثبيت-kestra-على-خادم-vps-أتمتة-ذاتية-الاستضافة","Instalar Kestra en un VPS: automatización self-hosted","Instale Kestra en su VPS: orquestación de workflows declarativos en YAML para sus pipelines de datos y ETL, self-hosted con Docker.",3,8,"2026-05-22T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[213],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Finstaller-kestra-vps-poster.svg",{"categorySlug":182,"appSlug":216},"kestra",true,1794270581937]