Docker Compose since version 2.1.1 has a new flag for the detached mode - --wait
.
Running docker-compose -d --wait
waits until containers are healthy and only then exits (containers of course still run in the background).
To make it work, it has to be defined what does healthy mean - each container the command is meant to wait for must have defined healthcheck
entry in docker-compose.yml
.
For example, we can verify that Postgres & MySQL is ready to accept connections with following configuration:
services:
postgres:
image: postgres:13.3
environment:
- POSTGRES_USER=test
- POSTGRES_DB=test
- POSTGRES_PASSWORD=test
healthcheck:
test: ["CMD", "pg_isready"]
interval: 3s
timeout: 5s
retries: 5
Healthcheck configuration
Let's break down the healthcheck configuration options:
test
- is a command to run - if it returns0
- container is healthy,1
- unhealthyinterval
- time to wait before first test is made and then between further test invocationstimeout
- time to wait until test command returnsretries
- the number of retries to runtest
until we give upstart_period
- assumed time that containers need to start and become healthy - iftest
returns1
during this time, it is not counted against the number of retries
Here are test
commands for some popular containers that I often use:
- Postgres:
[ "CMD", "pg_isready" ]
- MySQL:
[ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
- Redis:
[ "CMD", "redis-cli", "--raw", "incr", "ping" ]
- RabbitMQ:
rabbitmq-diagnostics -q ping
Result
And that's how it looks in action:
It is useful especially for chaining commands, for example - start services with Docker Compose and once they are ready, run application:
$ docker-compose up -d --wait && ./mvnw spring-boot:run