Using compose I want to start a service only after another service has exited with code 0.
I have mutiple needs for this functionality. The basic need is where I have:
The database service will start an empty database. My app needs it's schema setup in the database so I have a second service which will do this when it is run. When it is done this service will exit successfully - I can see this in my docker compose log file:
webservices_kong-migration_1 exited with code 0
I do not want the application service to start until after the database migration has completed.
I have the following in my docker-compose file for the application service:
depends_on: kong-database: condition: service_healthy kong-migration: condition: service_started
I know this is wrong because I can see in my docker-compose log that the application is started after the migration has started but before it has completed, causing the application to fail.
(I have been taking https://github.com/Kong/docker-kong/blob/master/compose/docker-compose.yml as an example)
Does docker-compose have functionality to do this or should I be considering another method?
This is a supplement to @zooblin 's answer
Since docker-compose
version 1.29, we can do it by condition: service_completed_successfully
In your scene, database service start will cost some time, so the migration scripts should be executed after database fully started.
And the application service should start after migration scripts executed successfully.
the docker-compose.yaml
may be like following(here we use cassandra as exmaple, for other database, you can just modify healthcheck
commands):
version: '3.8'
services:
applicaion-service:
image: your-applicaion-service:0.0.1
depends_on:
cassandra-init-keyspace:
condition: service_completed_successfully
cassandra:
image: cassandra:4.0.1
ports:
- "9042:9042"
healthcheck:
test: ["CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces"]
interval: 15s
timeout: 10s
retries: 10
cassandra-init-keyspace:
image: cassandra:4.0.1
depends_on:
cassandra:
condition: service_healthy
volumes:
- ./src/main/resources/cassandra/init.cql:/init.cql
command: /bin/bash -c "echo loading cassandra keyspace && cqlsh cassandra -f /init.cql"
Docker compose haven't any out-of-the-box solutions.
But exists a number of good implementations for solving this problem.
One of the better solutions is using service discovery as Consul and Autopilot model implemented in Joyent Containerpilot.
This model allows implementing dependencies between services even in docker swarm cluster where service dependency does not exist at all.
Containerpilot jobs model allow creating simple scripts to keep started services in the right order.
docker-compose
version 1.29 comes with build in functionality: service_completed_successfully
.
According to spec:
service_completed_successfully
- specifies that a dependency is expected to run to successful completion before starting a dependent service.
depends_on:
<service-name>:
condition: service_completed_successfully
For those who are looking for an answer, there're still no out-of-the-box solutions for this.
A workaround solution consists in using a wrapper script : https://docs.docker.com/compose/startup-order/
In Robert's case, you can imagine a script that loops and waits until the database service can no more be pinged (until the services has stopped).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With