Gestionar servicios con systemd: guía práctica
systemd es el gestor de servicios estándar en la mayoría de distribuciones Linux modernas. Aprende a crear tus propios servicios, controlarlos con systemctl y leer sus logs con journalctl.
enable, start, status— puedes registrar cualquier proceso como servicio con arranque automático, reinicio ante fallos y logs centralizados en el journal.Si tu servidor arranca servicios a medias, esto va contigo
Tienes un servidor en casa o en una VPS, y hay dos o tres scripts que necesitas que corran al arrancar. Los metiste en rc.local, o pusiste un @reboot en cron, y funciona… la mayoría de las veces. Pero cuando el proceso muere en silencio a las 3 de la mañana, te enteras porque algo deja de responder, no porque el sistema te haya avisado.
Quizá has oído hablar de systemd y lo has dejado pasar porque parece mucho aparato para lo que necesitas: unit files, targets, dependencias… Da la sensación de que es para sysadmins de empresa, no para alguien que mantiene su homelab en los ratos libres. Es normal pensarlo.
Este post es un tutorial directo. Al final tendrás un servicio real corriendo bajo systemd, configurado para arrancar solo, reiniciarse si cae, y con logs consultables desde un solo comando. No necesitas saber más de systemd del que vas a leer aquí para empezar a usarlo bien.
Por qué importa
Restart automático incluido
Con `Restart=on-failure` en el unit file, systemd relanza el proceso si muere. Sin cron ni watchdogs externos.
Logs sin configurar nada
`journalctl -u tu-servicio` muestra el historial completo desde el arranque, sin archivos de log separados.
Orden de arranque declarativo
`After=network.target` garantiza que tu servicio espera a que la red esté lista. Un campo, cero scripts.
Limita permisos fácilmente
Con `User=` y `Group=` en la sección [Service] el proceso corre sin root, reduciendo superficie de ataque.
Qué es systemd y por qué lo encuentras en casi todo
systemd es el sistema de init que arranca como proceso PID 1 cuando el kernel termina de cargarse. A partir de ahí, es el encargado de levantar todo lo demás: la red, el servidor SSH, el entorno gráfico, tus propios scripts… todo pasa por él.
Lo crearon Lennart Poettering y Kay Sievers en 2010. En pocos años desplazó a SysV init y Upstart en Debian, Ubuntu, Fedora, Arch, openSUSE y la mayoría de distribuciones de uso general. No está en todas: Alpine Linux usa OpenRC y Void Linux usa runit, así que si trabajas con esas distros, esto no aplica directamente.
Hay quien tiene opinión fuerte sobre systemd —la comunidad Linux rara vez se pone de acuerdo en nada fácilmente—, pero en la práctica, si tienes un homelab con Debian o Ubuntu, ya lo estás usando. Más vale conocerlo bien.
Los unit files: la pieza clave para definir un servicio
Un servicio en systemd se describe en un archivo de texto plano con extensión .service. Se llama unit file. Es lo que le dice a systemd cómo arrancar tu proceso, con qué usuario, cuándo hacerlo y qué hacer si falla.
Las tres secciones de un unit file
[Unit]— descripción y dependencias con otros servicios o recursos del sistema[Service]— cómo arrancar, parar y reiniciar el proceso[Install]— en qué punto del arranque debe activarse
Un ejemplo mínimo para un script Python que quieras dejar corriendo en tu servidor:
[Unit]
Description=Mi script de monitorización casero
After=network.target
[Service]
ExecStart=/home/javi/scripts/monitor.py
Restart=on-failure
User=javi
[Install]
WantedBy=multi-user.target
After=network.target le dice a systemd que espere a que la red esté disponible antes de arrancar. Restart=on-failure hace que si el proceso muere inesperadamente, systemd lo relance solo. Sin esas dos líneas, tienes un servicio frágil.
Dónde se guardan los unit files
En Debian y Ubuntu hay dos ubicaciones relevantes:
/lib/systemd/system/— unit files que instalan los paquetes del sistema. No los toques directamente./etc/systemd/system/— los tuyos, los que creas a mano. Si hay conflicto de nombres, estos tienen prioridad.
Crear tu primer servicio personalizado paso a paso
Supón que tienes un script en /opt/homelab/backup.sh que quieres ejecutar como servicio en segundo plano. Esto es lo que harías en Debian/Ubuntu:
1. Crea el unit file
sudo nano /etc/systemd/system/backup-homelab.service
Contenido del archivo:
[Unit]
Description=Backup homelab automatizado
After=network.target
[Service]
Type=simple
ExecStart=/bin/bash /opt/homelab/backup.sh
Restart=on-failure
User=javi
Group=javi
[Install]
WantedBy=multi-user.target
2. Recarga la configuración de systemd
Cada vez que creas o modificas un unit file, hay que avisar a systemd:
sudo systemctl daemon-reload
Sin este paso, systemd sigue viendo la versión anterior del archivo.
3. Habilita el servicio para que arranque con el sistema
sudo systemctl enable backup-homelab.service
Esto crea un symlink en el target de arranque. No arranca el servicio en ese momento, solo lo registra para el próximo boot.
4. Arráncalo manualmente para probarlo
sudo systemctl start backup-homelab.service
5. Comprueba que está corriendo
sudo systemctl status backup-homelab.service
Si ves Active: active (running), todo va bien. Si ves failed, el siguiente apartado te explica cómo investigar.
Comandos imprescindibles: systemctl en el día a día
Una vez que tienes servicios definidos, estos son los comandos que más usarás:
| Comando | Qué hace |
|---|---|
systemctl start servicio |
Arranca el servicio ahora |
systemctl stop servicio |
Para el servicio |
systemctl restart servicio |
Para y vuelve a arrancar |
systemctl reload servicio |
Recarga config sin matar el proceso (si el servicio lo soporta) |
systemctl enable servicio |
Lo activa para el arranque automático |
systemctl disable servicio |
Lo desactiva del arranque |
systemctl status servicio |
Estado actual y últimas líneas de log |
systemctl daemon-reload |
Recarga todos los unit files tras modificarlos |
Dos más que conviene tener a mano:
# Ver todos los servicios activos
systemctl list-units --type=service --state=running
# Ver los que han fallado
systemctl --failed
systemctl --failed es especialmente útil cuando algo no arranca y no sabes qué. Te da la lista de los servicios en estado failed directamente, sin tener que revisar cada uno a mano.
Leer logs con journalctl sin volverte loco
systemd tiene su propio sistema de logging: el journal. Los logs de todos los servicios van ahí, y se leen con journalctl. No necesitas buscar archivos dispersos por /var/log/ para cada servicio.
Comandos básicos:
# Logs de un servicio concreto
journalctl -u backup-homelab.service
# Solo las últimas 50 líneas
journalctl -u backup-homelab.service -n 50
# Seguir el log en tiempo real (como tail -f)
journalctl -u backup-homelab.service -f
# Logs del arranque actual
journalctl -u backup-homelab.service -b
Cuando algo falla, lo primero que hay que hacer es journalctl -u nombre-del-servicio -n 100. El 90% de las veces el error está en las últimas líneas: un path incorrecto, un usuario sin permisos, una dependencia que no se cargó.
Truco útil:
journalctl -xemuestra los últimos logs del journal completo con contexto extra. Sirve para ver qué pasó justo antes de que un servicio fallara al arrancar, especialmente cuando el problema está en algo de lo que depende y no en el propio servicio.
Seguridad y resiliencia básicas en tus servicios
Con tres líneas extra en el unit file ya tienes algo bastante más robusto que un script en cron o un nohup. No hace falta configuración avanzada para obtener un resultado decente.
Corre el servicio como un usuario sin privilegios
Por defecto, los servicios corren como root. Si tu script no necesita permisos de root, define un usuario:
[Service]
User=javi
Group=javi
Si el proceso tiene un bug gordo o se ve comprometido, el daño queda contenido al usuario javi y no afecta al sistema entero.
Resiliencia con Restart=
Restart=on-failure
RestartSec=5s
RestartSec añade una pausa antes de reintentar. Sin eso, si tu servicio falla en un bucle rápido, systemd lo relanza tan rápido que puede saturar el sistema. Cinco segundos es un buen punto de partida para servicios caseros.
Si quieres un timeout de parada limpia:
TimeoutStopSec=10
Evita que systemd espere indefinidamente a que un proceso termine. Si a los 10 segundos no ha parado limpiamente, lo mata.
Secretos fuera del unit file
Si tu servicio necesita una contraseña o un token de API, no los pongas directamente en ExecStart=. Pueden quedar expuestos en la salida de systemctl status o en logs. Usa un archivo de entorno:
[Service]
EnvironmentFile=/etc/homelab/secrets.env
Y en /etc/homelab/secrets.env (con permisos 600, solo root puede leerlo):
API_TOKEN=tu_token_aqui
Así los secretos quedan separados del unit file, que puede ser consultado por cualquier usuario del sistema con systemctl cat.
Preguntas frecuentes
Q: ¿Vale systemd para mis scripts caseros de arranque?
A: Funciona muy bien para eso. Cualquier script que necesites que arranque con el sistema y se reinicie si falla puede convertirse en un unit file .service en minutos. Solo necesitas definir el comando en ExecStart= y añadir Restart=on-failure.
Q: ¿Qué pasa si mi servicio muere solo en mitad del día?
A: Con Restart=on-failure en el unit file, systemd lo relanza automáticamente sin que tengas que hacer nada. Puedes ver cuántas veces ha caído y por qué con journalctl -u nombre-del-servicio, sin buscar archivos de log dispersos.
Q: ¿Por qué no usar un simple script en /etc/rc.local?
A: Puedes, pero rc.local no gestiona reinicios automáticos, no integra logs en el journal y no controla el orden de arranque con precisión. Con systemd tienes todo eso con cuatro líneas en un unit file y sin mantener lógica de reinicio a mano.
Q: »¿Cómo
A: »Añadiendo
Q: »¿Qué
A: »En











Deja una respuesta