Cómo hacer que Docker Compose espere a los contenedores de dependencia


Docker Compose le permite iniciar varios contenedores ejecutando un solo comando. Esto simplifica la creación de servicios complejos formados por varios componentes independientes.

Sin embargo, esto no siempre es lo suficientemente bueno. Algunos de sus contenedores pueden tener dependencias entre sí que rompen la aplicación si no se pueden cumplir. En esta guía, le mostraremos cómo puede configurar sus servicios de Compose para adaptarse a estas dependencias, lo que hace posible iniciar contenedores en orden.

Índice de contenidos
  1. Los basicos
  2. Esperando la preparación
  3. Esperando una salida exitosa del contenedor
  4. Resumen

Los basicos

Docker Compose admite una depends_on campo en docker.compose.yml archivos Los servicios pueden incluir los nombres de sus hermanos en depends_on. Esto evita que el contenedor se inicie hasta que los servicios de los que depende estén activos.

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db
  web-app:
    image: example.com/web-app:latest
    depends_on:
      - api
  db:
    image: mysql:8.0

En este ejemplo, el depends_on campos hacen que los servicios se inicien en el siguiente orden:

Las dependencias de cada servicio se resuelven recursivamente. El servicio que define cada depends_on El campo se inicia en último lugar, al final de la cadena. Cuando un servicio depende de varios otros contenedores, se iniciarán en el orden en que aparecen en el depends_on campo.

La cadena de servicios se usa a la inversa cuando detiene una pila con docker-compose stop. Con el ejemplo anterior, el web-app el contenedor se eliminará primero, luego api y db. Esto evita que las solicitudes a la web-app el contenedor falle cuando comience una operación de desmontaje.

Esperando la preparación

El valor por defecto depends_on la configuración solo espera a que los contenedores dependientes comienzo. En el ejemplo anterior, Compose puede crear el api contenedor tan pronto como db se está ejecutando, incluso si el servidor de la base de datos dentro del contenedor no está listo para recibir conexiones. Esto significa depends_on rara vez es suficiente por sí solo.

Puede combinar la función con comprobaciones de estado para evitar que los contenedores se inicien hasta que sus dependencias estén realmente listas. Para usar esta capacidad, anide un condition campo bajo depends_on con service_healthy como su valor:

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db
    healthcheck:
      test: curl --fail http://127.0.0.1 || exit 1
      interval: 10s
      retries: 5
      start_period: 5s
      timeout: 10s
  web-app:
    image: example.com/web-app:latest
    depends_on:
      api:
        condition: service_healthy
  db:
    image: mysql:8.0

Ahora el api El contenedor tiene un comando de control de salud adjunto. los web-app se indica que el servicio no se inicie hasta api se ha creado con un resultado de control de estado correcto. Esto será una vez que la API comience a responder a las solicitudes y el curl el comando sale con un código de estado cero.

Esperando una salida exitosa del contenedor

En algunos casos, su dependencia puede ser un contenedor de un solo uso que desea ejecutar hasta el final. Puede esperar este tipo de dependencia configurando el condition campo a service_completed_successfully. Esto es útil cuando tiene un script de configuración de primera ejecución que se ejecuta en otro contenedor.

services:
  app:
    image: example.com/app:latest
    depends_on:
      config_builder:
        condition: service_completed_successfully
    volumes:
      - config:/opt/app/config
  config_builder:
    image: example.com/config_builder:latest
    env:
      - EXAMPLE_KEY
      - ANOTHER_KEY
    volumes:
      - config:/output
volumes:
  config:

Este ejemplo muestra cómo una imagen dependiente podría ejecutar un comando que escribe un archivo de configuración en un volumen compartido por app. Después de escribir los datos, el config_builder el contenedor se detiene con un código de salida cero. Compose inicia automáticamente el app servicio ya que se ha cumplido su condición de dependencia.

En algunas situaciones depends_on con un condition aún podría no ser suficiente para adaptarse a su caso de uso. Puede agregar herramientas externas para implementar manualmente controles de estado y manejar enlaces entre contenedores.

Wait-for-It es un script de utilidad que envuelve otro proceso. Ejecutará el comando que especifique después de que se cumpla una determinada condición. Esto se puede usar para definir procedimientos de control de salud independientemente del soporte integrado de Docker.

Aquí está cómo usar healthcheck para esperar a que se pueda acceder a un puerto de contenedores vinculado:

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db
  web-app:
    image: example.com/web-app:latest
    depends_on:
      - api
    command: ["./wait-for-it.sh", "api:8080", "--", "node", "app.js"]
  db:
    image: mysql:8.0

Aquí hemos vuelto a hacer que Docker Compose solo espere el api contenedor para comienzo. los web-app servicio acepta la responsabilidad de comprobar si api es saludable. Utiliza el script Wait-for-It para detectar cuándo se puede acceder al contenedor en el puerto 8080. Wait-for-It luego iniciará el comando real del contenedor de la aplicación web, definido como node app.js.

Es mejor reservar este enfoque para situaciones específicas en las que no puede configurar un control de estado adecuado con Docker. Puede ser necesario cuando usa una imagen de terceros que no se puede configurar para ejecutar un comando de verificación de estado. Wait-for-It proporciona una forma de detectar si un puerto está sirviendo tráfico como reemplazo suplente. Si bien no es infalible, a menudo es un buen indicador de la salubridad de un contenedor.

Resumen

Por defecto, Docker Compose inicia simultáneamente todos los servicios en su pila. Esto a menudo no es deseable cuando los enlaces entre los servicios crean relaciones de dependencia padre-hijo.

los depends_on El campo le permite definir una secuencia de inicio para sus servicios. Compose creará cada nuevo contenedor en orden, garantizando que el anterior haya comenzado antes de que se agregue el siguiente contenedor.

Puede esperar a que salga el contenedor anterior o informar un control de estado positivo agregando un condition a la definición de dependencia. En situaciones en las que no se pueden usar las comprobaciones de estado, puede utilizar herramientas como Wait-for-It para que los contenedores principales detecten cuándo están listas sus dependencias.

Descubre más contenido

Subir Change privacy settings