Una de las funcionalidades más potentes de Podman es su integración nativa con systemd. A diferencia de Docker, Podman está diseñado para ejecutarse sin daemon, lo que permite convertir cualquier contenedor en un servicio systemd gestionable con systemctl. En este artículo aprenderás a generar, instalar y gestionar unidades systemd para tus contenedores.

Generar unidades systemd con podman generate systemd

Podman incluye el comando generate systemd que produce archivos de unidad systemd listos para usar a partir de contenedores o pods existentes. Las opciones clave son:

  • --name: usa el nombre del contenedor como nombre de la unidad.
  • --files: escribe directamente los archivos .service en el directorio actual.
  • --new: genera una unidad que crea el contenedor desde cero en cada inicio (en lugar de requerir un contenedor pre-existente).
# Crear un contenedor de ejemplo
podman run -d --name mi-app --restart=always -p 8080:80 nginx:alpine

# Generar unidad systemd
podman generate systemd --name --files --new mi-app

# Esto crea: container-mi-app.service

La bandera --new es fundamental para entornos productivos: sin ella, systemd espera que el contenedor ya exista antes de iniciarlo. Con --new, systemd ejecuta podman run con los parámetros originales cada vez que arranca el servicio, asegurando que el contenedor se recrea limpiamente incluso tras un reinicio del servidor.

Instalar, iniciar y monitorear el servicio

Una vez generado el archivo .service, el siguiente paso es copiarlo al directorio de systemd, recargar la configuración y habilitar el servicio para que arranque automáticamente con el sistema.

# Copiar la unidad al directorio de systemd
cp container-mi-app.service /etc/systemd/system/

# Recargar systemd y habilitar el servicio
systemctl daemon-reload
systemctl enable container-mi-app.service
systemctl start container-mi-app.service

# Verificar estado
systemctl status container-mi-app.service

Para ver los logs del contenedor como cualquier otro servicio del sistema, usa journalctl con el nombre de la unidad. Esto es mucho más cómodo que ejecutar podman logs cada vez, especialmente cuando tienes múltiples contenedores corriendo como servicios.

# Ver logs del servicio en tiempo real
journalctl -u container-mi-app.service -f

# Ver últimas 50 líneas
journalctl -u container-mi-app.service -n 50 --no-pager

# Filtrar por prioridad (errores solamente)
journalctl -u container-mi-app.service -p err -n 20

Restart policies y recomendaciones de producción

Al convertir contenedores en servicios systemd, la política de reinicio se define en dos niveles:

  1. Podman (--restart): usado al crear el contenedor (--restart=always, on-failure, no).
  2. Systemd (Restart=): definido en el archivo .service generado (Restart=always, on-failure, on-abnormal).

La recomendación para producción es usar --new junto con Restart=always en systemd. De esta forma, si el contenedor falla, systemd lo reinicia automáticamente, y si el servidor se apaga, al encenderse systemd recrea el contenedor desde cero con los parámetros originales. También puedes combinar con RestartSec=5s para evitar reinicios en bucle demasiado rápidos.

# Ejemplo completo: contenedor con restart policy
podman run -d --name app-prod \
  --restart=on-failure:5 \
  -p 443:443 \
  my-registry/webapp:latest

# Generar con --new para que systemd lo cree desde cero
podman generate systemd --name --files --new app-prod

# Editar Restart= siempre en el .service antes de copiar
sed -i "s/Restart=on-failure/Restart=always/" container-app-prod.service
sed -i "/^Restart=/a RestartSec=5s" container-app-prod.service

# Copiar y activar
cp container-app-prod.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now container-app-prod.service

Con esta configuración, tu aplicación corre como cualquier servicio Linux nativo. Puedes gestionarla con systemctl, monitorearla con journalctl, y systemd se encarga del ciclo de vida completo. Así cierras el círculo entre desarrollo local con Podman y operaciones con herramientas estándar del sistema.