4.2Fiabilizar: healthcheck y políticas de reinicio
Lo esencial en 30 segundos
- restart resucita, healthcheck prueba : la política de reinicio relanza el contenedor tras fallo o reinicio ; la prueba de salud periódica dice si el servicio está realmente listo (no solo iniciado).
- depends_on ordena, condition: service_healthy espera lo realmente listo : sin condición, el orden de arranque es solo una esperanza — con un healthcheck en la base, la API solo arranca sobre probado sano.
- Reflejo de Idir : unless-stopped por defecto (respeta las paradas voluntarias), y Up no es healthy : un servicio Up pero unhealthy es un enfermo por curar, no un servicio que funciona.
Mini-caso hilado — Idir acaba con los fallos del lunes por la mañana
Idir, devops junior en Argel, se despierta con una alerta : tras un corte eléctrico, la API está iniciada pero la base no estaba lista — fallos en cascada. Añade restart: unless-stopped a cada servicio duradero, un healthcheck pg_isready en la base, y hace depender la API de service_healthy. Luego mata la base para verificar : relanzamiento automático y espera probada. Segundo hito del hilo : la stack se reinicia sola y solo enruta hacia lo probado sano.
Continuación del caso 4.1 — la imagen publicada por Idir corre ahora de forma autónoma.
1. restart : la política de resurrección
restart: unless-stopped relanza el contenedor tras un fallo o un reinicio de máquina, salvo parada voluntaria — el buen defecto para un servicio duradero. always relanza incluso tras un stop manual (reservado a servicios críticos), on-failure solo relanza en caso de error. Sin política, como antes de la corrección de Idir, un fallo nocturno espera hasta la mañana.
Elegir según la intención : duradero (unless-stopped), crítico que nunca debe pararse (always), tarea que solo debe reanudarse en fallo (on-failure). Y se evita always en todas partes : reinicia incluso sus paradas voluntarias.
2. healthcheck : « listo » vale más que « iniciado »
depends_on ordena, healthcheck prueba : un comando probado periódicamente (pg_isready para Postgres, una petición HTTP para una API) pasa el servicio a healthy. Entonces se puede esperar lo realmente listo (condition: service_healthy) en lugar de esperar que la base haya terminado de arrancar.
La prueba debe apuntar al servicio real (una petición, no la simple presencia del proceso) : eso es lo que hace desaparecer los fallos de arranque « base no lista » de Idir.
3. Tres estados, tres reacciones
starting (se espera), healthy (se enruta), unhealthy (se alerta, ya no se envía tráfico). docker compose ps muestra el estado : un servicio Up pero unhealthy es un enfermo por curar (logs, diagnóstico), no un servicio que funciona.
Ajustar la frecuencia con medida : bastante a menudo para detectar (10 a 30 segundos), con reintentos repetidos para evitar falsos positivos. Una prueba demasiado agresiva se pasa señalando ; demasiado rara, pierde los fallos.
¿Lo sabías?
Up es el pulso ; healthy es la forma.
🔎 Ejemplo concreto — 🔎 Ejemplo concreto — Postgres que prueba su salud
La stack de Idir : la API solo arranca sobre base probada lista.
services:
bdd:
image: postgres:16.4
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 10s
retries: 5
api:
build: ./api
depends_on:
bdd:
condition: service_healthy
Lectura : la API solo arranca sobre base probada lista.
Lección : los fallos de arranque « base no lista » desaparecen.
Vocabulario de la sección
- restart
- Política de relanzamiento automático del contenedor : no, on-failure, always, unless-stopped.
Ejemplo sencillo: Idir pone unless-stopped : relanza tras fallo o reinicio, pero respeta su stop manual.
Lo que no es: un reinicio manual a las 3 de la mañana tras cada fallo.
Reflejo: servicio duradero : declarar una política restart.
- healthcheck
- Prueba periódica que prueba la SALUD REAL del servicio (petición, no simple proceso).
Ejemplo sencillo: pg_isready prueba que la base de Idir acepta realmente las conexiones.
Lo que no es: un simple orden de arranque sin verificación.
Reflejo: dependencia crítica : probar el servicio real.
- healthy / unhealthy
- Estado sano o enfermo según la última prueba de salud — independiente de que el proceso corra.
Ejemplo sencillo: La base de Idir está Up pero unhealthy : diagnostica en lugar de enrutar.
Lo que no es: un simple marcha o paro.
Reflejo: Up + unhealthy : curar, no enrutar.
- condition: service_healthy
- En depends_on : esperar que la dependencia esté probada sana antes de arrancar.
Ejemplo sencillo: La API de Idir espera la base healthy en lugar de esperar.
Lo que no es: un orden de inicio sin garantía de disponibilidad.
Reflejo: arranque ordenado : exigir la condición, no solo el orden.
En la práctica — En práctica — Hacer su stack autónoma
- Añada restart: unless-stopped a cada servicio duradero.
- Añada un healthcheck a la base (pg_isready).
- Haga depender la API de service_healthy.
- Mate la base (kill) : observe relanzamiento + espera probada.
Guion listo para decir — explicar la fiabilización al equipo (30 s)
« Soy Idir : cada servicio duradero se reinicia solo tras un fallo, la base prueba que está lista con una prueba real, y la API espera esa prueba antes de arrancar. Se acabaron los despertares tras un corte : la stack se levanta sola. »
Para decir en revisión : muestre la prueba kill de la base delante del equipo.
Modelo copiar-pegar — base probada + API que espera (Compose)
services:
bdd:
image: postgres:16.4
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 10s
timeout: 5s
retries: 5
api:
build: ./api
restart: unless-stopped
depends_on:
bdd:
condition: service_healthy
API web por probar en HTTP
Como Idir pero con una prueba de petición web en la página de inicio : el servicio está healthy cuando responde realmente.
Servicio crítico 24/7
restart: always asumido y documentado : incluso un stop manual relanza — reservar a los casos realmente críticos.
Tarea puntual
restart: on-failure : solo se relanza en caso de error, no tras un éxito normal.
Falsa sensación de seguridad
depends_on sin condición + prueba que apunta al contenedor equivocado : corregir hacia service_healthy y prueba real.
✓ Buenas prácticas
- unless-stopped por defecto en duradero.
- Probar el servicio real (petición, no el PID).
- Leer el estado health en compose ps.
✗ Errores frecuentes
- always en todas partes (reinicia incluso sus stops).
- depends_on sin condición (falsa sensación).
- Healthcheck que prueba el contenedor equivocado.
Puntos clave
- restart resucita, healthcheck prueba.
- depends_on + condición = orden real.
- Up no es healthy.
- unless-stopped : el buen defecto.
Reto 48h — aplique mañana
En su stack real : añada unless-stopped + healthcheck + condición, mate la base y observe relanzamiento y espera probada.
- Sé declarar una política restart adaptada.
- Sé escribir un healthcheck que prueba lo realmente listo.
- Sé hacer esperar service_healthy y leer el estado.
Preguntas frecuentes
¿Healthcheck o simple reintento en la app?
Ambos : los reintentos hacen la app robusta en todas partes, el healthcheck hace la stack observable y planificable. Son aliados, no competidores.
¿Qué frecuencia de prueba?
Bastante a menudo para detectar (10 a 30 segundos), con reintentos repetidos para evitar falsos positivos. Una prueba demasiado agresiva señala sin parar ; demasiado rara, pierde los fallos.
Un servicio está « Up (unhealthy) ». ¿Qué hay que entender?