systemd Services

Gestión de servicios con systemd

Unit File Estándar

Ubicación: /etc/systemd/system/mi-proyecto.service

[Unit]
Description=Mi Proyecto Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=illanes00
WorkingDirectory=/srv/projects/mi-proyecto
EnvironmentFile=-/srv/projects/mi-proyecto/.env
ExecStart=/srv/projects/mi-proyecto/venv/bin/python run.py
Restart=on-failure
StartLimitIntervalSec=120
StartLimitBurst=10

# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full

[Install]
WantedBy=multi-user.target

Comandos de Gestión

Acción Comando
Ver estado systemctl status proyecto.service
Iniciar sudo systemctl start proyecto.service
Detener sudo systemctl stop proyecto.service
Reiniciar sudo systemctl restart proyecto.service
Habilitar (boot) sudo systemctl enable proyecto.service
Deshabilitar sudo systemctl disable proyecto.service
Recargar daemon sudo systemctl daemon-reload

Logs con journalctl

# Últimas 50 líneas
journalctl -u proyecto.service -n 50

# Seguir logs en tiempo real
journalctl -u proyecto.service -f

# Logs desde hoy
journalctl -u proyecto.service --since today

# Logs de la última hora
journalctl -u proyecto.service --since "1 hour ago"

# Logs sin paginación (para grep)
journalctl -u proyecto.service --no-pager

Variables de Entorno

Desde archivo .env

# En el unit file
EnvironmentFile=-/srv/projects/mi-proyecto/.env

El - hace que no falle si el archivo no existe.

Inline en el unit

[Service]
Environment="PORT=8105"
Environment="HOST=0.0.0.0"

Debug: Servicio No Inicia

  1. Ver estado detallado:
systemctl status proyecto.service
  1. Ver logs completos:
journalctl -u proyecto.service --no-pager -n 100
  1. Verificar unit file:
systemctl cat proyecto.service
  1. Verificar permisos:
ls -la /srv/projects/proyecto/
ls -la /srv/projects/proyecto/venv/bin/python
  1. Verificar puerto libre:
ss -tlnp | grep 8105
  1. Ejecutar manualmente:
cd /srv/projects/proyecto
source .env
./venv/bin/python run.py

Reinicio Automático

El Restart=on-failure hace que systemd reinicie el servicio si falla (exit code != 0).

Límites configurados: - StartLimitIntervalSec=120 - Ventana de 2 minutos - StartLimitBurst=10 - Máximo 10 reinicios en esa ventana

Si se excede, el servicio entra en estado failed y necesita intervención manual:

# Resetear contador de fallos
sudo systemctl reset-failed proyecto.service

# Iniciar de nuevo
sudo systemctl start proyecto.service

User Services (sin sudo)

Para servicios que no necesitan privilegios:

# Crear directorio
mkdir -p ~/.config/systemd/user/

# Crear unit file
cp proyecto.service ~/.config/systemd/user/

# Gestionar
systemctl --user daemon-reload
systemctl --user enable --now proyecto.service

Habilitar linger para que corra sin sesión activa:

sudo loginctl enable-linger illanes00