Una aplicación puede fallar al conectarse a PostgreSQL aunque el contenedor de la base de datos aparezca como running. Ese estado indica que el proceso está en ejecución, pero no garantiza que PostgreSQL ya acepte conexiones.
Una espera fija de diez segundos fallará si la base de datos tarda más en arrancar. Con un healthcheck y depends_on, Docker Compose puede esperar a que PostgreSQL acepte conexiones antes de crear el servicio que la utiliza.
Cuándo espera depends_on
La forma corta de depends_on establece qué servicio arranca primero, pero no espera a que la base de datos acepte conexiones. Con condition: service_healthy, Compose espera a que el healthcheck de la base de datos tenga éxito antes de crear el servicio que depende de ella. Docker documenta ambas situaciones.
La condición service_healthy se comprueba durante el arranque. Si la base de datos deja de responder más tarde, la aplicación debe gestionar el fallo: reintentar la conexión o informar del error.
Ejemplo con PostgreSQL
Para este ejemplo necesitas Docker Engine o Docker Desktop funcionando y Docker Compose con el comando docker compose. Guarda lo siguiente en compose.yaml, dentro de una carpeta nueva. Son dos servicios de demostración: PostgreSQL y un cliente que ejecuta una consulta y termina.
services:
db:
image: postgres:18
environment:
POSTGRES_USER: demo
POSTGRES_PASSWORD: solo-para-esta-demo
POSTGRES_DB: demo
healthcheck:
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U demo -d demo"]
interval: 5s
timeout: 3s
retries: 5
start_period: 20s
consulta:
image: postgres:18
environment:
PGPASSWORD: solo-para-esta-demo
depends_on:
db:
condition: service_healthy
command: ["psql", "-h", "db", "-U", "demo", "-d", "demo", "-c", "SELECT 1;"]
La contraseña es un valor de ejemplo para esta prueba local. La base de datos no publica un puerto hacia el equipo anfitrión. El cliente utiliza db, el nombre del servicio dentro de la red de Compose.
La comprobación usa pg_isready, una herramienta incluida en la imagen de PostgreSQL. Este comando indica si el servidor acepta conexiones. No comprueba que las migraciones hayan terminado ni que el usuario pueda ejecutar las consultas de la aplicación. Tampoco necesita credenciales correctas para consultar el estado del servidor. Referencia de PostgreSQL.
Qué comprueba el healthcheck
interval establece la separación entre comprobaciones; timeout limita cada intento y retries define cuántos fallos consecutivos llevan a unhealthy. Durante start_period, los fallos no cuentan para alcanzar ese límite. Si una comprobación tiene éxito antes de terminar ese periodo, los fallos posteriores ya cuentan. Por tanto, start_period: 20s no obliga a esperar veinte segundos si el servicio está disponible antes. Semántica de HEALTHCHECK.
Ajusta los tiempos a tu servicio. Una base de datos que restaura información al arrancar puede necesitar más tiempo. Si compruebas una API, define qué respuesta indica que está disponible y evita consultas que consuman muchos recursos. Compose permite configurar un healthcheck diferente para cada servicio. Referencia de healthcheck.
El archivo se ha validado con docker compose config --quiet. No se ha probado el arranque de los contenedores.
Comprobar el arranque
Primero valida el archivo y después ejecuta el proyecto:
docker compose config --quiet
docker compose up --abort-on-container-exit --exit-code-from consulta
La consulta debería devolver 1 y el cliente debería terminar con código de salida cero. --exit-code-from consulta hace que el comando devuelva el código de salida de ese servicio. La opción --abort-on-container-exit detiene los demás contenedores cuando termina el cliente. Referencia de compose up.
Para retirar los contenedores y sus volúmenes anónimos de esta demo, ejecuta docker compose down --volumes desde esa misma carpeta. No reutilices esa orden en un proyecto con datos que necesites conservar.
Unhealthy no provoca reinicios
Un contenedor puede seguir ejecutándose mientras su estado de salud es unhealthy. Docker Engine no lo reinicia automáticamente por ese cambio. Las políticas de reinicio, como on-failure o unless-stopped, responden a la terminación del proceso o a la parada del contenedor, según cada política. Un healthcheck fallido no activa por sí solo esas políticas. Políticas de reinicio de Docker.
Define qué hacer cuando falle el healthcheck: enviar una alerta, investigar el servicio o reiniciarlo si eso puede resolver el problema. La comprobación informa del estado; por sí sola no ejecuta esas acciones.
