Skip to content
rodolfo.gg
Go back

Guía para administración de servicios con systemd.

CC BY-NC-ND 4.0
Rodolfo González González

Guía para administración de servicios con systemd.

Introducción

Hace mucho, mucho tiempo, yo inicié administrando un servidor Solaris durante unos meses. De ahí pasé a Slackware, porque era lo que había. Y luego a Red Hat. En esos tiempos, el ciclo de vida de los servicios se manejaba sin complicaciones con SysVinit. Sin embargo, en algún punto del camino, alguien tuvo la idea de complicar las cosas.

Entra systemd.

Y, pues, dado que Ubuntu, Debian y la mayoría de las distribuciones derivadas usan este sistema, no queda de otra más que aprender un poco de él.


Tabla de contenido

Tabla de contenido

1. Introducción: qué es systemd y qué administra

systemd es el sistema de inicialización y administrador de servicios predominante en muchas distribuciones modernas de Linux. Su proceso principal suele ejecutarse como PID 1 y se encarga de arrancar el sistema, administrar servicios, montar sistemas de archivos, iniciar sockets, programar tareas, manejar sesiones, recolectar logs a través de journald y coordinar dependencias entre componentes del sistema.

En la administración diaria, el comando central es systemctl. Con él se consultan, arrancan, detienen, habilitan, deshabilitan, reinician, recargan, enmascaran y administran unidades de systemd.

Un “servicio” en systemd normalmente corresponde a una unidad con extensión .service, por ejemplo:

Sin embargo, systemd no administra únicamente servicios. Administra diferentes tipos de unidades: servicios, sockets, timers, targets, mounts, automounts, paths, slices, scopes, devices y swaps.

Ejemplo básico para ver el estado de un servicio:

Terminal window
systemctl status ssh.service

Explicación del comando:

Ejemplo alternativo:

Terminal window
systemctl status ssh

Este comando suele resolver ssh como ssh.service, siempre que no exista ambigüedad con otra unidad del mismo nombre y distinta extensión.


2. Conceptos fundamentales: unidades, servicios y targets

2.1 Unidad

Una unidad es un objeto administrado por systemd. Cada unidad se define mediante un archivo de configuración llamado unit file. El nombre de la unidad indica su tipo por medio de su extensión.

Ejemplos:

nginx.service
ssh.socket
apt-daily.timer
multi-user.target
home.mount

2.2 Servicio

Una unidad .service describe cómo iniciar, detener, recargar y supervisar un proceso o conjunto de procesos.

Ejemplo de un archivo de servicio mínimo:

[Unit]
Description=Servicio de ejemplo
After=network.target
[Service]
ExecStart=/usr/local/bin/mi-servicio
Restart=on-failure
[Install]
WantedBy=multi-user.target

Explicación de las secciones:

2.3 Target

Un target es una unidad que agrupa otras unidades. Es comparable, de forma aproximada, a los antiguos runlevels de SysVinit.

Targets comunes:

Ver el target predeterminado:

Terminal window
systemctl get-default

Explicación:

Establecer el target predeterminado:

Terminal window
sudo systemctl set-default multi-user.target

Explicación:

Ejemplo para un servidor sin escritorio gráfico:

Terminal window
sudo systemctl set-default multi-user.target

Ejemplo para un equipo con entorno gráfico:

Terminal window
sudo systemctl set-default graphical.target

3. Inspección básica del sistema y de los servicios

Antes de instalar, modificar o borrar servicios, conviene saber cómo inspeccionar el estado del sistema.

3.1 Listar servicios activos

Terminal window
systemctl list-units --type=service --state=running

Explicación:

Ejemplo:

Terminal window
systemctl list-units --type=service --state=running

Útil para revisar qué procesos están siendo administrados por systemd en este momento.

3.2 Listar todos los servicios cargados

Terminal window
systemctl list-units --type=service --all

Explicación:

Ejemplo:

Terminal window
systemctl list-units --type=service --all

3.3 Listar archivos de unidad instalados

Terminal window
systemctl list-unit-files --type=service

Explicación:

La salida suele incluir estados como:

Ejemplo:

Terminal window
systemctl list-unit-files --type=service | grep nginx

3.4 Ver el estado detallado de un servicio

Terminal window
systemctl status nginx.service

Explicación:

Ejemplo:

Terminal window
systemctl status nginx.service

Salida típica abreviada:

● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since ...
Main PID: 1234 (nginx)
Tasks: 5
Memory: 12.3M

3.5 Ver propiedades internas de una unidad

Terminal window
systemctl show nginx.service

Explicación:

Ejemplo filtrando una propiedad:

Terminal window
systemctl show nginx.service --property=MainPID

Explicación:

Otro ejemplo:

Terminal window
systemctl show nginx.service --property=FragmentPath --property=DropInPaths

Explicación:

3.6 Ver el archivo unit efectivo

Terminal window
systemctl cat nginx.service

Explicación:

Ejemplo:

Terminal window
systemctl cat nginx.service

4. Instalación de servicios

Instalar un servicio puede significar dos cosas distintas:

  1. Instalar un paquete del sistema que trae su propio servicio systemd.
  2. Crear e instalar manualmente un archivo .service para una aplicación propia.

Este cubre la instalación mediante gestores de paquetes. La creación manual se cubre en el siguiente.

4.1 Instalar un servicio en Debian, Ubuntu y derivados

Ejemplo con nginx:

Terminal window
sudo apt update
sudo apt install nginx

Explicación del primer comando:

Explicación del segundo comando:

Ejemplo completo:

Terminal window
sudo apt update
sudo apt install nginx
systemctl status nginx.service

Después de instalar un paquete, conviene verificar si el servicio quedó activo o habilitado:

Terminal window
systemctl is-active nginx.service
systemctl is-enabled nginx.service

Explicación:

4.2 Instalar un servicio en Fedora, RHEL, CentOS Stream, Rocky Linux o AlmaLinux

Ejemplo con nginx:

Terminal window
sudo dnf install nginx

Explicación:

Ejemplo completo:

Terminal window
sudo dnf install nginx
systemctl status nginx.service

En muchas distribuciones de la familia Red Hat, instalar un paquete no implica necesariamente arrancarlo ni habilitarlo. Para habilitarlo y arrancarlo:

Terminal window
sudo systemctl enable --now nginx.service

Explicación:

4.3 Instalar un servicio en Arch Linux y derivados

Ejemplo con nginx:

Terminal window
sudo pacman -Syu nginx

Explicación:

Luego se puede habilitar y arrancar:

Terminal window
sudo systemctl enable --now nginx.service

4.4 Ver qué archivos instaló un paquete

En Debian/Ubuntu:

Terminal window
dpkg -L nginx | grep systemd

Explicación:

Ejemplo:

Terminal window
dpkg -L nginx | grep '\.service$'

Explicación:

En Fedora/RHEL:

Terminal window
rpm -ql nginx | grep '\.service$'

Explicación:


5. Creación manual de servicios propios

Cuando una aplicación no viene empaquetada como servicio systemd, se puede crear una unidad manualmente.

5.1 Ejemplo de aplicación propia

Supongamos que existe un binario en:

/usr/local/bin/miapp

Y que queremos ejecutarlo como servicio.

Primero se recomienda crear un usuario de sistema dedicado:

Terminal window
sudo useradd --system --home /var/lib/miapp --create-home --shell /usr/sbin/nologin miapp

Explicación:

En algunas distribuciones la ruta de nologin puede ser distinta. Se puede verificar con:

Terminal window
command -v nologin

5.2 Crear directorios para la aplicación

Terminal window
sudo mkdir -p /etc/miapp /var/lib/miapp /var/log/miapp
sudo chown -R miapp:miapp /var/lib/miapp /var/log/miapp
sudo chmod 0750 /var/lib/miapp /var/log/miapp

Explicación:

5.3 Crear el archivo unit

Terminal window
sudo editor /etc/systemd/system/miapp.service

Contenido sugerido:

[Unit]
Description=Mi aplicación de ejemplo
Documentation=https://example.com/docs/miapp
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=miapp
Group=miapp
WorkingDirectory=/var/lib/miapp
EnvironmentFile=-/etc/miapp/miapp.env
ExecStart=/usr/local/bin/miapp --config /etc/miapp/config.yaml
Restart=on-failure
RestartSec=5s
TimeoutStartSec=30s
TimeoutStopSec=30s
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target

Explicación de [Unit]:

Explicación de [Service]:

Explicación de [Install]:

5.4 Recargar systemd después de crear o modificar una unidad

Terminal window
sudo systemctl daemon-reload

Explicación:

Ejemplo completo:

Terminal window
sudo editor /etc/systemd/system/miapp.service
sudo systemctl daemon-reload
sudo systemctl status miapp.service

5.5 Verificar sintaxis de una unidad

Terminal window
systemd-analyze verify /etc/systemd/system/miapp.service

Explicación:

Ejemplo:

Terminal window
systemd-analyze verify /etc/systemd/system/miapp.service

Si el comando no imprime errores, la unidad probablemente es válida desde el punto de vista sintáctico.

5.6 Habilitar y arrancar el servicio propio

Terminal window
sudo systemctl enable --now miapp.service

Explicación:

Verificar:

Terminal window
systemctl status miapp.service
journalctl -u miapp.service -n 50 --no-pager

Explicación:


6. Arrancar, detener, reiniciar y recargar servicios

6.1 Arrancar un servicio

Terminal window
sudo systemctl start nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl start nginx.service
systemctl status nginx.service

6.2 Detener un servicio

Terminal window
sudo systemctl stop nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl stop nginx.service
systemctl is-active nginx.service

6.3 Reiniciar un servicio

Terminal window
sudo systemctl restart nginx.service

Explicación:

Ejemplo:

Terminal window
sudo nginx -t
sudo systemctl restart nginx.service

Explicación:

6.4 Recargar un servicio sin reiniciarlo

Terminal window
sudo systemctl reload nginx.service

Explicación:

Ejemplo:

Terminal window
sudo nginx -t
sudo systemctl reload nginx.service

6.5 Recargar si es posible, reiniciar si no lo es

Terminal window
sudo systemctl reload-or-restart nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl reload-or-restart nginx.service

6.6 Reiniciar sólo si el servicio ya está activo

Terminal window
sudo systemctl try-restart nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl try-restart nginx.service

6.7 Recargar o reiniciar sólo si está activo

Terminal window
sudo systemctl reload-or-try-restart nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl reload-or-try-restart nginx.service

6.8 Matar procesos de un servicio

Terminal window
sudo systemctl kill nginx.service

Explicación:

Ejemplo enviando SIGKILL:

Terminal window
sudo systemctl kill --signal=SIGKILL nginx.service

Explicación:

Ejemplo enviando SIGHUP:

Terminal window
sudo systemctl kill --signal=SIGHUP nginx.service

Explicación:


7. Activar, desactivar, enmascarar y desenmascarar servicios

En systemd hay que distinguir entre iniciar y habilitar:

7.1 Habilitar un servicio para que arranque automáticamente

Terminal window
sudo systemctl enable nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl enable nginx.service
systemctl is-enabled nginx.service

7.2 Habilitar y arrancar en un solo paso

Terminal window
sudo systemctl enable --now nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl enable --now nginx.service
systemctl status nginx.service

7.3 Deshabilitar un servicio

Terminal window
sudo systemctl disable nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl disable nginx.service
systemctl is-enabled nginx.service
systemctl is-active nginx.service

7.4 Deshabilitar y detener en un solo flujo

No existe un único subcomando tradicional equivalente a “disable —now” en todas las versiones históricas, aunque muchas versiones modernas aceptan disable --now. Para máxima compatibilidad, se puede hacer explícitamente:

Terminal window
sudo systemctl disable nginx.service
sudo systemctl stop nginx.service

Explicación:

Ejemplo usando --now cuando está disponible:

Terminal window
sudo systemctl disable --now nginx.service

Explicación:

7.5 Rehabilitar un servicio

Terminal window
sudo systemctl reenable nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl reenable nginx.service

7.6 Enmascarar un servicio

Terminal window
sudo systemctl mask nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl mask nginx.service
systemctl status nginx.service

Resultado conceptual:

Loaded: masked (Reason: Unit nginx.service is masked.)

7.7 Enmascarar y detener inmediatamente

Terminal window
sudo systemctl mask --now nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl mask --now nginx.service

7.8 Desenmascarar un servicio

Terminal window
sudo systemctl unmask nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl unmask nginx.service
sudo systemctl enable --now nginx.service

7.9 Consultar si un servicio está activo o habilitado

Terminal window
systemctl is-active nginx.service
systemctl is-enabled nginx.service

Explicación:

Ejemplo en un script:

Terminal window
if systemctl is-active --quiet nginx.service; then
echo "Nginx está activo"
else
echo "Nginx no está activo"
fi

Explicación:


8. Configuración de servicios con archivos unit y drop-ins

8.1 No editar directamente archivos de paquetes

Los servicios instalados por paquetes suelen tener sus unidades en rutas como:

/usr/lib/systemd/system/
/lib/systemd/system/

Dependiendo de la distribución, una u otra puede ser la ruta principal. No conviene editar estos archivos directamente, porque una actualización del paquete puede sobrescribir cambios.

La ubicación recomendada para cambios locales es:

/etc/systemd/system/

8.2 Editar un servicio con drop-in

Terminal window
sudo systemctl edit nginx.service

Explicación:

Ejemplo para añadir reinicio automático:

Terminal window
sudo systemctl edit nginx.service

Contenido:

[Service]
Restart=on-failure
RestartSec=3s

Después:

Terminal window
sudo systemctl daemon-reload
sudo systemctl restart nginx.service

Explicación:

8.3 Editar el archivo completo de una unidad

Terminal window
sudo systemctl edit --full nginx.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl edit --full nginx.service
sudo systemctl daemon-reload
sudo systemctl restart nginx.service

8.4 Ver diferencias entre archivos originales y overrides

Terminal window
systemd-delta

Explicación:

Ejemplo:

Terminal window
systemd-delta --type=extended

Explicación:

Otro ejemplo:

Terminal window
systemd-delta nginx.service

8.5 Resetear overrides de una unidad

Para eliminar un drop-in creado con systemctl edit:

Terminal window
sudo rm -rf /etc/systemd/system/nginx.service.d
sudo systemctl daemon-reload
sudo systemctl restart nginx.service

Explicación:

Si se usó systemctl edit --full, se debe borrar la copia completa:

Terminal window
sudo rm -f /etc/systemd/system/nginx.service
sudo systemctl daemon-reload
sudo systemctl restart nginx.service

Explicación:

8.6 Sobrescribir listas en drop-ins

Algunas directivas de systemd aceptan múltiples valores. Para reemplazarlas por completo en un drop-in, primero se vacían.

Ejemplo con ExecStart:

[Service]
ExecStart=
ExecStart=/usr/local/bin/miapp --modo produccion

Explicación:

Ejemplo completo:

Terminal window
sudo systemctl edit miapp.service

Contenido:

[Service]
ExecStart=
ExecStart=/usr/local/bin/miapp --config /etc/miapp/prod.yaml

Aplicar:

Terminal window
sudo systemctl daemon-reload
sudo systemctl restart miapp.service

8.7 Configurar reinicios automáticos

Drop-in:

[Service]
Restart=on-failure
RestartSec=10s
StartLimitIntervalSec=300
StartLimitBurst=5

Explicación:

Comandos:

Terminal window
sudo systemctl edit miapp.service
sudo systemctl daemon-reload
sudo systemctl restart miapp.service

8.8 Configurar dependencias y orden de arranque

Ejemplo:

[Unit]
After=network-online.target postgresql.service
Wants=network-online.target
Requires=postgresql.service

Explicación:

Ejemplo de drop-in:

Terminal window
sudo systemctl edit miapp.service

Contenido:

[Unit]
After=network-online.target postgresql.service
Wants=network-online.target
Requires=postgresql.service

Aplicar:

Terminal window
sudo systemctl daemon-reload
sudo systemctl restart miapp.service

9. Variables de entorno, usuarios, permisos y directorios de trabajo

9.1 Variables de entorno inline

[Service]
Environment="APP_ENV=production" "APP_PORT=8080"

Explicación:

Ejemplo:

Terminal window
sudo systemctl edit miapp.service

Contenido:

[Service]
Environment="APP_ENV=production" "LOG_LEVEL=info"

Aplicar:

Terminal window
sudo systemctl daemon-reload
sudo systemctl restart miapp.service

9.2 Variables desde archivo EnvironmentFile

Archivo:

Terminal window
sudo install -d -m 0750 -o root -g miapp /etc/miapp
sudo editor /etc/miapp/miapp.env

Contenido del archivo:

Terminal window
APP_ENV=production
APP_PORT=8080
LOG_LEVEL=info

Unit file:

[Service]
EnvironmentFile=/etc/miapp/miapp.env

Explicación:

[Service]
EnvironmentFile=-/etc/miapp/miapp.env

Ejemplo completo:

Terminal window
sudo editor /etc/miapp/miapp.env
sudo systemctl restart miapp.service

Nota: si sólo se cambia el contenido de EnvironmentFile, normalmente basta con reiniciar el servicio. Si se cambia el unit file para añadir o quitar la directiva EnvironmentFile=, entonces se requiere daemon-reload.

9.3 Ejecutar como usuario dedicado

[Service]
User=miapp
Group=miapp

Explicación:

Ejemplo de creación del usuario:

Terminal window
sudo useradd --system --home /var/lib/miapp --create-home --shell /usr/sbin/nologin miapp

9.4 Configurar directorio de trabajo

[Service]
WorkingDirectory=/var/lib/miapp

Explicación:

Ejemplo:

[Service]
WorkingDirectory=/opt/miapp
ExecStart=/opt/miapp/bin/miapp

9.5 Crear directorios automáticamente con systemd

systemd puede crear directorios runtime, de estado, cache y logs para un servicio.

Ejemplo:

[Service]
User=miapp
Group=miapp
RuntimeDirectory=miapp
StateDirectory=miapp
CacheDirectory=miapp
LogsDirectory=miapp

Explicación:

Ejemplo de uso:

[Service]
User=miapp
Group=miapp
StateDirectory=miapp
WorkingDirectory=/var/lib/miapp
ExecStart=/usr/local/bin/miapp

9.6 Usar DynamicUser

[Service]
DynamicUser=yes
StateDirectory=miapp
ExecStart=/usr/local/bin/miapp

Explicación:

Ejemplo:

[Unit]
Description=Servicio con usuario dinámico
[Service]
DynamicUser=yes
StateDirectory=miapp
ExecStart=/usr/local/bin/miapp --data-dir /var/lib/miapp
[Install]
WantedBy=multi-user.target

10. Logs, diagnóstico y solución de problemas

10.1 Ver logs de un servicio

Terminal window
journalctl -u nginx.service

Explicación:

Ejemplo:

Terminal window
journalctl -u nginx.service

10.2 Ver últimas líneas de log

Terminal window
journalctl -u nginx.service -n 100 --no-pager

Explicación:

Ejemplo:

Terminal window
journalctl -u nginx.service -n 100 --no-pager

10.3 Seguir logs en tiempo real

Terminal window
journalctl -u nginx.service -f

Explicación:

Ejemplo:

Terminal window
journalctl -u miapp.service -f

10.4 Ver logs desde el último arranque

Terminal window
journalctl -u nginx.service -b

Explicación:

Ejemplo:

Terminal window
journalctl -u nginx.service -b --no-pager

10.5 Ver logs de un arranque anterior

Terminal window
journalctl --list-boots

Explicación:

Luego:

Terminal window
journalctl -b -1 -u nginx.service

Explicación:

10.6 Ver errores del sistema

Terminal window
journalctl -p err -b

Explicación:

Ejemplo:

Terminal window
journalctl -p warning..alert -b --no-pager

Explicación:

10.7 Diagnosticar servicios fallidos

Terminal window
systemctl --failed

Explicación:

Ejemplo:

Terminal window
systemctl --failed

Ver detalles de una unidad fallida:

Terminal window
systemctl status miapp.service
journalctl -u miapp.service -b -n 200 --no-pager

10.8 Resetear estado fallido

Terminal window
sudo systemctl reset-failed miapp.service

Explicación:

Ejemplo:

Terminal window
sudo systemctl reset-failed miapp.service
systemctl status miapp.service

Resetear todos los fallos registrados:

Terminal window
sudo systemctl reset-failed

10.9 Revisar tiempos de arranque

Terminal window
systemd-analyze

Explicación:

Ejemplo:

Terminal window
systemd-analyze blame

Explicación:

Ejemplo con ruta crítica:

Terminal window
systemd-analyze critical-chain

Explicación:

10.10 Ver árbol de dependencias

Terminal window
systemctl list-dependencies nginx.service

Explicación:

Ejemplo inverso:

Terminal window
systemctl list-dependencies --reverse nginx.service

Explicación:


11. Desinstalar, borrar y limpiar servicios

Este distingue varias operaciones que a menudo se confunden.

11.1 Detener antes de desinstalar

Terminal window
sudo systemctl stop nginx.service

Explicación:

11.2 Deshabilitar antes de desinstalar

Terminal window
sudo systemctl disable nginx.service

Explicación:

Ejemplo combinado:

Terminal window
sudo systemctl disable --now nginx.service

Explicación:

11.3 Desinstalar un paquete en Debian/Ubuntu

Remover el paquete conservando configuración:

Terminal window
sudo apt remove nginx

Explicación:

Remover el paquete y purgar configuración gestionada por el paquete:

Terminal window
sudo apt purge nginx

Explicación:

Eliminar dependencias que ya no se usan:

Terminal window
sudo apt autoremove

Explicación:

Ejemplo completo:

Terminal window
sudo systemctl disable --now nginx.service
sudo apt purge nginx
sudo apt autoremove

11.4 Desinstalar un paquete en Fedora/RHEL

Terminal window
sudo dnf remove nginx

Explicación:

Ejemplo:

Terminal window
sudo systemctl disable --now nginx.service
sudo dnf remove nginx

11.5 Desinstalar un paquete en Arch Linux

Terminal window
sudo pacman -R nginx

Explicación:

Remover paquete y dependencias no usadas instaladas como dependencias:

Terminal window
sudo pacman -Rs nginx

Explicación:

Ejemplo:

Terminal window
sudo systemctl disable --now nginx.service
sudo pacman -Rs nginx

11.6 Borrar un servicio manual creado en /etc/systemd/system

Supongamos que se creó manualmente:

/etc/systemd/system/miapp.service

Proceso recomendado:

Terminal window
sudo systemctl disable --now miapp.service
sudo rm -f /etc/systemd/system/miapp.service
sudo systemctl daemon-reload
sudo systemctl reset-failed miapp.service

Explicación:

Si el servicio tenía drop-ins:

Terminal window
sudo rm -rf /etc/systemd/system/miapp.service.d
sudo systemctl daemon-reload

Explicación:

11.7 Borrar datos, logs y configuración de una aplicación propia

Después de remover el unit file, si se desea borrar completamente la aplicación:

Terminal window
sudo rm -rf /etc/miapp /var/lib/miapp /var/log/miapp /var/cache/miapp

Explicación:

Ejemplo más seguro, listando antes:

Terminal window
sudo find /etc/miapp /var/lib/miapp /var/log/miapp /var/cache/miapp -maxdepth 2 -print

Luego, si se confirma que las rutas son correctas:

Terminal window
sudo rm -rf /etc/miapp /var/lib/miapp /var/log/miapp /var/cache/miapp

11.8 Borrar usuario y grupo de un servicio

Terminal window
sudo userdel miapp

Explicación:

Si se desea borrar también su home, dependiendo de cómo fue creado:

Terminal window
sudo userdel --remove miapp

Explicación:

Nota: si el directorio home fue compartido, contiene datos necesarios o se ubica en una ruta sensible, conviene revisar manualmente antes.

11.9 Limpiar unidades huérfanas o no encontradas

Después de borrar servicios manualmente:

Terminal window
sudo systemctl daemon-reload
systemctl list-units --type=service --all | grep miapp

Si aparece como fallida:

Terminal window
sudo systemctl reset-failed miapp.service

Si aparece como enmascarada:

Terminal window
sudo systemctl unmask miapp.service
sudo systemctl daemon-reload

11.10 Borrar un servicio enmascarado manualmente

Si existe un enlace como:

/etc/systemd/system/miapp.service -> /dev/null

Se puede desenmascarar:

Terminal window
sudo systemctl unmask miapp.service

O revisar manualmente:

Terminal window
ls -l /etc/systemd/system/miapp.service

Si se confirma que es un enlace a /dev/null:

Terminal window
sudo rm -f /etc/systemd/system/miapp.service
sudo systemctl daemon-reload

12. Servicios de usuario: systemd —user

systemd también puede administrar servicios por usuario, sin privilegios de root. Estos servicios pertenecen a la sesión del usuario y se configuran normalmente bajo:

~/.config/systemd/user/

12.1 Crear un servicio de usuario

Terminal window
mkdir -p ~/.config/systemd/user
editor ~/.config/systemd/user/mi-tarea.service

Contenido:

[Unit]
Description=Servicio de usuario de ejemplo
[Service]
ExecStart=/home/usuario/bin/mi-tarea
Restart=on-failure
[Install]
WantedBy=default.target

Explicación:

12.2 Recargar unidades de usuario

Terminal window
systemctl --user daemon-reload

Explicación:

12.3 Habilitar y arrancar un servicio de usuario

Terminal window
systemctl --user enable --now mi-tarea.service

Explicación:

12.4 Ver logs de usuario

Terminal window
journalctl --user -u mi-tarea.service

Explicación:

12.5 Permitir que servicios de usuario sigan tras cerrar sesión

Terminal window
loginctl enable-linger usuario

Explicación:

Ejemplo:

Terminal window
sudo loginctl enable-linger deploy

Esto es útil para servicios de usuario ejecutados por una cuenta de despliegue.

Desactivar linger:

Terminal window
sudo loginctl disable-linger deploy

13. Timers: reemplazo práctico de cron para servicios periódicos

Los timers de systemd permiten ejecutar servicios de forma programada.

13.1 Crear un servicio ejecutable por timer

Archivo:

Terminal window
sudo editor /etc/systemd/system/backup-miapp.service

Contenido:

[Unit]
Description=Backup de MiApp
[Service]
Type=oneshot
User=miapp
Group=miapp
ExecStart=/usr/local/bin/backup-miapp

Explicación:

13.2 Crear el timer

Archivo:

Terminal window
sudo editor /etc/systemd/system/backup-miapp.timer

Contenido:

[Unit]
Description=Ejecuta backup de MiApp diariamente
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
Unit=backup-miapp.service
[Install]
WantedBy=timers.target

Explicación:

13.3 Habilitar y arrancar el timer

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable --now backup-miapp.timer

Explicación:

13.4 Listar timers

Terminal window
systemctl list-timers --all

Explicación:

Ejemplo:

Terminal window
systemctl list-timers --all | grep backup-miapp

13.5 Ejecutar manualmente el servicio del timer

Terminal window
sudo systemctl start backup-miapp.service

Explicación:


14. Seguridad y endurecimiento de servicios

systemd permite aplicar medidas de aislamiento sin modificar la aplicación.

14.1 Proteger el sistema de archivos

Ejemplo de drop-in:

[Service]
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/miapp /var/log/miapp

Explicación:

Aplicación:

Terminal window
sudo systemctl edit miapp.service
sudo systemctl daemon-reload
sudo systemctl restart miapp.service

14.2 Restringir privilegios

[Service]
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=true

Explicación:

14.3 Restringir capacidades Linux

[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE

Explicación:

Ejemplo para una aplicación que escucha en el puerto 80:

[Service]
User=miapp
Group=miapp
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
ExecStart=/usr/local/bin/miapp --listen :80

14.4 Analizar seguridad de una unidad

Terminal window
systemd-analyze security miapp.service

Explicación:

Ejemplo:

Terminal window
systemd-analyze security nginx.service

14.5 Endurecimiento razonable de un servicio propio

Ejemplo:

[Service]
User=miapp
Group=miapp
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/var/lib/miapp /var/log/miapp
Restart=on-failure

Explicación:


15. Buenas prácticas operativas

15.1 Usar nombres claros

Para servicios propios, use nombres descriptivos:

miapp-api.service
miapp-worker.service
miapp-scheduler.service

Esto facilita logs, monitoreo y administración.

15.2 Usar usuarios dedicados

Evite ejecutar servicios como root salvo que sea estrictamente necesario. Use:

[Service]
User=miapp
Group=miapp

15.3 Separar configuración, datos y binarios

Convención común:

/usr/local/bin/miapp # binario instalado manualmente
/etc/miapp/ # configuración
/var/lib/miapp/ # datos persistentes
/var/log/miapp/ # logs propios, si aplica
/run/miapp/ # archivos runtime temporales

15.4 Validar antes de reiniciar

Ejemplo con Nginx:

Terminal window
sudo nginx -t && sudo systemctl reload nginx.service

Explicación:

Ejemplo con una aplicación propia que soporte validación:

Terminal window
/usr/local/bin/miapp --check-config /etc/miapp/config.yaml && sudo systemctl restart miapp.service

15.5 Usar drop-ins para cambios locales

Preferible:

Terminal window
sudo systemctl edit miapp.service

Evitar, salvo necesidad justificada:

Terminal window
sudo editor /usr/lib/systemd/system/miapp.service

Razón: los archivos bajo /usr/lib/systemd/system o /lib/systemd/system suelen pertenecer a paquetes y pueden ser sobrescritos por actualizaciones.

15.6 Documentar overrides

Un drop-in puede incluir comentarios:

[Service]
# Reinicio automático para tolerar fallos transitorios de red.
Restart=on-failure
RestartSec=5s

15.7 Revisar logs después de cualquier cambio

Terminal window
sudo systemctl restart miapp.service
systemctl status miapp.service
journalctl -u miapp.service -b -n 100 --no-pager

15.8 Evitar rm -rf sin verificar rutas

Antes de borrar datos:

Terminal window
sudo find /var/lib/miapp -maxdepth 2 -print

Después, si se confirma:

Terminal window
sudo rm -rf /var/lib/miapp

15.9 Usar daemon-reload cuando corresponda

Debe usarse después de:

Comando:

Terminal window
sudo systemctl daemon-reload

No suele ser necesario después de modificar únicamente un archivo cargado con EnvironmentFile=, a menos que se haya cambiado el unit file mismo.

15.10 Diferenciar reload de daemon-reload

Terminal window
sudo systemctl reload nginx.service

Recarga la configuración de Nginx.

Terminal window
sudo systemctl daemon-reload

Recarga la configuración de systemd, es decir, los unit files.

Son operaciones distintas.


16. Directorios y archivos importantes

16.1 Unit files del sistema

/etc/systemd/system/

Uso:

Ejemplos:

/etc/systemd/system/miapp.service
/etc/systemd/system/nginx.service.d/override.conf
/etc/systemd/system/multi-user.target.wants/nginx.service

/usr/lib/systemd/system/

Uso:

Ejemplos:

/usr/lib/systemd/system/sshd.service
/usr/lib/systemd/system/docker.service

/lib/systemd/system/

Uso:

Ejemplos:

/lib/systemd/system/ssh.service
/lib/systemd/system/nginx.service

/run/systemd/system/

Uso:


16.2 Unit files de usuario

~/.config/systemd/user/

Uso:

Ejemplo:

/home/usuario/.config/systemd/user/mi-tarea.service

/etc/systemd/user/

Uso:


/usr/lib/systemd/user/

Uso:


16.3 Configuración general de systemd

/etc/systemd/system.conf

Uso:


/etc/systemd/user.conf

Uso:


/etc/systemd/journald.conf

Uso:


/etc/systemd/logind.conf

Uso:


16.4 Logs del journal

/run/log/journal/

Uso:


/var/log/journal/

Uso:

Crear almacenamiento persistente del journal:

Terminal window
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald.service

Explicación:


16.5 Configuración de aplicaciones

/etc/<servicio>/

Uso:

Ejemplos:

/etc/nginx/
/etc/ssh/
/etc/postgresql/
/etc/miapp/

16.6 Datos persistentes

/var/lib/<servicio>/

Uso:

Ejemplos:

/var/lib/postgresql/
/var/lib/mysql/
/var/lib/docker/
/var/lib/miapp/

16.7 Logs clásicos por archivo

/var/log/<servicio>/

Uso:

Ejemplos:

/var/log/nginx/
/var/log/apache2/
/var/log/miapp/

16.8 Archivos runtime

/run/<servicio>/

Uso:

Ejemplos:

/run/nginx.pid
/run/sshd.pid
/run/miapp/

16.9 tmpfiles.d

/etc/tmpfiles.d/
/usr/lib/tmpfiles.d/
/run/tmpfiles.d/

Uso:

Ejemplo de archivo:

/etc/tmpfiles.d/miapp.conf

Contenido:

d /run/miapp 0750 miapp miapp -
d /var/log/miapp 0750 miapp miapp -

Aplicar manualmente:

Terminal window
sudo systemd-tmpfiles --create /etc/tmpfiles.d/miapp.conf

Explicación:


16.10 sysusers.d

/etc/sysusers.d/
/usr/lib/sysusers.d/
/run/sysusers.d/

Uso:

Ejemplo:

/etc/sysusers.d/miapp.conf

Contenido:

u miapp - "Usuario de sistema para MiApp" /var/lib/miapp /usr/sbin/nologin

Aplicar manualmente:

Terminal window
sudo systemd-sysusers /etc/sysusers.d/miapp.conf

Explicación:


16.11 Rutas relacionadas con habilitación

Cuando se ejecuta:

Terminal window
sudo systemctl enable miapp.service

systemd puede crear enlaces simbólicos como:

/etc/systemd/system/multi-user.target.wants/miapp.service -> /etc/systemd/system/miapp.service

Explicación:


16.12 Archivos de entorno frecuentes

No existe una única ubicación universal, pero estas son comunes:

/etc/default/<servicio> # Debian/Ubuntu en algunos paquetes
/etc/sysconfig/<servicio> # RHEL/Fedora en algunos paquetes
/etc/<servicio>/<servicio>.env

Ejemplos:

/etc/default/nginx
/etc/sysconfig/sshd
/etc/miapp/miapp.env

Estos archivos sólo afectan al servicio si el unit file tiene una directiva como:

EnvironmentFile=/etc/miapp/miapp.env

Fuentes de referencia


Apéndice rápido: chuleta de comandos frecuentes

Terminal window
# Ver estado
systemctl status servicio.service
# Arrancar ahora
sudo systemctl start servicio.service
# Detener ahora
sudo systemctl stop servicio.service
# Reiniciar
sudo systemctl restart servicio.service
# Recargar configuración del servicio
sudo systemctl reload servicio.service
# Habilitar al arranque
sudo systemctl enable servicio.service
# Habilitar y arrancar ahora
sudo systemctl enable --now servicio.service
# Deshabilitar al arranque
sudo systemctl disable servicio.service
# Deshabilitar y detener ahora
sudo systemctl disable --now servicio.service
# Enmascarar para impedir arranque
sudo systemctl mask servicio.service
# Desenmascarar
sudo systemctl unmask servicio.service
# Recargar definiciones de unidades
sudo systemctl daemon-reload
# Ver logs
journalctl -u servicio.service
# Ver logs recientes
journalctl -u servicio.service -n 100 --no-pager
# Seguir logs en tiempo real
journalctl -u servicio.service -f
# Ver unidades fallidas
systemctl --failed
# Limpiar estado fallido
sudo systemctl reset-failed servicio.service
# Ver archivo unit efectivo
systemctl cat servicio.service
# Crear override local
sudo systemctl edit servicio.service
# Validar unidad
systemd-analyze verify /etc/systemd/system/servicio.service

Share this post on:

Previous Post
Cómo convertir un JPEG o PNG a ICO en la CLI de Linux
Next Post
Inclusión de gráficos hecha sencilla: Mermaid.