Crear un servicio systemd para cualquier aplicación
Dedicados & VPS
23

Crear un servicio systemd para cualquier aplicación

Cuando tienes un proceso que debe correr siempre en tu VPS (una API, un bot, un worker, un script de monitoreo), la forma correcta de mantenerlo vivo es convertirlo en un servicio systemd. Systemd es el gestor de servicios por defecto en casi todas las distribuciones Linux modernas, y aprender a escribir un archivo de unit te ahorra montones de dolores de cabeza.

Qué es systemd

Systemd es el primer proceso que arranca Linux (PID 1) y se encarga de iniciar, detener y supervisar el resto de servicios del sistema. Si un servicio muere, systemd puede reiniciarlo; si necesita arrancar al boot, systemd lo hace antes de que alguien inicie sesión. Todo se configura con archivos de texto plano llamados units, que terminan en .service.

Anatomía de un archivo .service

Crea un archivo en /etc/systemd/system/miapp.service con esta plantilla básica:

[Unit]
Description=Mi aplicación personalizada
After=network.target

[Service]
Type=simple
User=appuser
Group=appuser
WorkingDirectory=/opt/miapp
ExecStart=/opt/miapp/venv/bin/python /opt/miapp/main.py
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Cada sección tiene un propósito específico. Vamos a desglosarlas.

Sección [Unit]

Description es texto libre que aparece cuando consultas el estado del servicio. After=network.target le dice a systemd que no arranque este servicio hasta que la red esté lista. Si tu app necesita base de datos local, puedes poner After=postgresql.service.

Sección [Service]

Aquí va lo importante. Type=simple es lo más común: systemd asume que el proceso definido en ExecStart es el servicio mismo y no se bifurca. User y Group indican con qué identidad correr; nunca uses root salvo que sea estrictamente necesario. WorkingDirectory es el equivalente a hacer cd antes de ejecutar, útil si tu app usa rutas relativas.

ExecStart es el comando completo para arrancar la app. Importante: usa siempre rutas absolutas, porque systemd no carga el PATH del usuario como lo haría una sesión interactiva. Restart=on-failure hace que systemd reinicie el servicio si termina con código de error, y RestartSec=5 le dice que espere 5 segundos entre intentos.

Variables de entorno

Si necesitas pasar variables, tienes dos opciones. La directa:

Environment="API_KEY=abc123"
Environment="DEBUG=false"

La recomendada para secretos es usar un archivo separado:

EnvironmentFile=/etc/miapp.env

Y en /etc/miapp.env pones las variables una por línea. Asegúrate de que ese archivo tenga permisos restrictivos (chmod 600).

Habilitar y gestionar el servicio

Después de crear el archivo, recarga systemd para que lo detecte y activa el servicio:

sudo systemctl daemon-reload
sudo systemctl enable miapp
sudo systemctl start miapp

El enable registra el servicio para arrancar al boot; el start lo lanza de inmediato. Puedes combinarlos con enable --now. Para ver el estado actual:

sudo systemctl status miapp

Leer logs con journalctl

Todo lo que tu aplicación imprima a stdout y stderr queda capturado automáticamente en el journal de systemd. Para consultar logs:

sudo journalctl -u miapp
sudo journalctl -u miapp -f
sudo journalctl -u miapp --since "1 hour ago"

El flag -f los sigue en tiempo real como un tail -f, y --since acepta expresiones humanas muy cómodas. Esto elimina la necesidad de redirigir logs a archivos manualmente.

Comandos diarios

Los que vas a usar constantemente: systemctl restart miapp, systemctl stop miapp, systemctl disable miapp. Cada vez que edites el archivo .service, recuerda correr daemon-reload antes del restart para que los cambios surtan efecto.