Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Compose Wait til dependency container is fully up before launching

I'm working with a docker service using docker-compose, and I have a service that depends on anther.

I've used the depends_on key, but the service with the dependency launches prior to the depending service being completely up.

version: '3'

services:
  KeyManager:
    image: cjrutherford/keymanager
    deploy:
      replicas: 1
    ports:
      - '3220:3220'
    networks:
      - privnet
  YellowDiamond:
    image: cjrutherford/server
    depends_on:
      - KeyManager
    deploy:
      replicas: 1
    ports:
      - '3000:3000'
    networks:
      - privnet
      - web
networks:
  privnet:
    internal: true
  web:

Both of these are node applications, and the keymanager is required to be running to accept requests before the server launches. Can I add a timeout? or send a trigger in the app? it's just launching way too early to get the key from the manager.

like image 735
Chris Rutherford Avatar asked Apr 03 '19 18:04

Chris Rutherford


People also ask

Why does docker compose does not wait for container to be ready before moving on to?

There's a good reason for this: The problem of waiting for a database (for example) to be ready is really just a subset of a much larger problem of distributed systems. In production, your database could become unavailable or move hosts at any time. Your application needs to be resilient to these types of failures.

How can we control the start up order of services in docker compose?

You can control the order of service startup and shutdown with the depends_on option. Compose always starts and stops containers in dependency order, where dependencies are determined by depends_on , links , volumes_from , and network_mode: "service:..." .

Do I need to run docker compose up every time?

Solution. Majority of the time, you will most likely want to bring up all of the services listed in your docker-compose. yml and have the containers run their default command, so you would want to use up . There will be times when you need to run a one-off process/task to support your application.

What does depends on mean in docker compose?

depends_on is a Docker Compose keyword to set the order in which services must start and stop. For example, suppose we want our web application, which we'll build as a web-app image, to start after our Postgres container.


2 Answers

I've often found using a wait-for-it bash script much more effective than the built in health check to docker-compose.

This runs a TCP health check against a given port and waits until this is complete before starting to run a process.

Sample code:

version: "2"
services:
  web:
    build: .
    ports:
      - "80:8000"
    depends_on:
      - "db"
    command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
  db:
    image: postgres

Here's some docs:

  • https://docs.docker.com/compose/startup-order/
  • https://github.com/vishnubob/wait-for-it
like image 144
devingops Avatar answered Oct 19 '22 19:10

devingops


You are probably looking for docker compose healthcheck and the Long Syntax form of depends_on.

The behavior for this feature has changed between docker-copmose versions, so here is the updated way to do so (this docker-compose file works as is):

services:
  db:
    image: postgres
    environment:
      - POSTGRES_USER=king
      - POSTGRES_DB=kong
      - POSTGRES_HOST_AUTH_METHOD=trust
    healthcheck:
      test: pg_isready -U postgres

  web:
    image: alpine
    depends_on: 
      db:
        condition: service_healthy

Then run docker-compose run web, and it will wait for the database before starting.

There is also a more detailed form of the healthcheck directive:

healthcheck:
  test: ["CMD-SHELL", "pg_isready -U postgres"]
  interval: 10s
  timeout: 5s
  retries: 5

Notes:

  1. This requires docker-compose 1.27.0 or higher
  2. In order for this to work, the compose file must not contain version directive (reference)
like image 23
DannyB Avatar answered Oct 19 '22 20:10

DannyB