~/docs /DevOps/Systemd/Crear servicio

DevOps

Crear servicio

Imported from Notion: Crear servicio

updated:: 2026.07.10

Qué resuelve

Plantilla y flujo para crear un .service propio en systemd: usuario, directorio de trabajo, variables, reinicio automático, activación y logs.


Estructura recomendada

Archivo:

/etc/systemd/system/mi-app.service

Plantilla:

[Unit]
Description=Mi aplicación
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=deploy
Group=deploy
WorkingDirectory=/opt/mi-app
EnvironmentFile=-/etc/mi-app/env
ExecStart=/opt/mi-app/.venv/bin/python /opt/mi-app/app.py
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Crear servicio

sudo nano /etc/systemd/system/mi-app.service

Validar y activar:

sudo systemctl daemon-reload
sudo systemctl enable --now mi-app.service
systemctl status mi-app.service

Ver logs:

journalctl -u mi-app.service -f

Variables de entorno

Archivo:

/etc/mi-app/env

Contenido:

APP_ENV=production
PORT=3000

Permisos:

sudo chown root:root /etc/mi-app/env
sudo chmod 600 /etc/mi-app/env

[!NOTE] 💡 El prefijo - en EnvironmentFile=-/etc/mi-app/env permite que el servicio arranque aunque el archivo no exista. Quita el - si debe ser obligatorio.


Opciones importantes

OpciónUso
User=Ejecutar sin root
WorkingDirectory=Directorio base del proceso
ExecStart=Comando principal
Restart=on-failureReiniciar solo si falla
RestartSec=5Espera antes de reiniciar
EnvironmentFile=Variables desde archivo
After=Orden de arranque
WantedBy=Target para enable

Editar con override

Para modificar una unidad sin tocar el archivo original:

sudo systemctl edit mi-app.service

Ver resultado efectivo:

systemctl cat mi-app.service

Reinicio seguro tras cambios

sudo systemctl daemon-reload
sudo systemctl restart mi-app.service
systemctl status mi-app.service
journalctl -u mi-app.service -n 100 --no-pager

Errores comunes

  • Ejecutar como root sin necesidad.

  • Usar rutas relativas en ExecStart.

  • Olvidar daemon-reload después de editar.

  • Poner secretos directamente en el .service.

  • No revisar logs tras activar.

  • Usar Restart=always sin entender si el proceso puede entrar en bucle.


Checklist final

  • ExecStart usa rutas absolutas.

  • El usuario existe y tiene permisos.

  • Variables sensibles están fuera del .service.

  • Ejecuté daemon-reload.

  • Activé con enable --now.

  • Revisé status y journalctl.

- EOF -