'How to make container wait for other container in Docker Compose
I'm following this tutorial and try to start the infrastructure using Docker Compose instead of shell scripts calling docker client. Everything works fine, except gitlab container is started before gitlab-postgreql and gitlab-redis, thus failing, as it expects those services be already running.
I tried to use depends_on attributes, but it didn't solve the problem. As far as I know, it doesn't help, if other containers are faster to start. After a research I figured out, Docker Compose doesn't provide out-of-the-box solution to control container creation order.
How can this be? I can't believe such a fundamental feature have left unimplemented. Seems like Docker is stumbling on it's own cleverness and forgets the basics. Now, how do I control the container creation order without some crazy support scripts (which would make whole configuration more cluttered than just using scripts / docker client for everything in the first place)
Here is the docker-compose.yml as it is
version: '2'
services:
gitlab-postgresql:
image: sameersbn/postgresql:9.4-3
volumes:
- /srv/docker/gitlab/postgresql:/var/lib/postgresql
environment:
- DB_NAME=gitlabhq_production
- DB_USER=gitlab
- DB_PASS=password
gitlab-redis:
image: sameersbn/redis:latest
volumes:
- /srv/docker/gitlab/redis:/var/lib/redis
depends_on:
- "gitlab-postgresql"
gitlab:
image: sameersbn/gitlab:7.14.3
volumes:
- /srv/docker/gitlab/gitlab:/home/git/data
ports:
- "2222:22"
- "8080:80"
environment:
- GITLAB_PORT=8080
- GITLAB_SSH_PORT=2222
depends_on:
- gitlab-postgresql
- gitlab-redis
registry:
image: registry:2
volumes:
- /srv/docker/registry/data:/var/lib/registry
ports:
- "5000:5000"
depends_on:
- "gitlab"
jenkins:
image: jenkins:1.609.3
volumes:
- /srv/docker/jenkins/home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/bin/docker
- /usr/lib/x86_64-linux-gnu/libapparmor.so.1.1.0:/lib/x86_64-linux-gnu/libapparmor.so.1
ports:
- "8081:8080"
- "50000:50000"
user: root
depends_on:
- "registry"
Solution 1:[1]
gitlab container is started before gitlab-postgreql and gitlab-redis,
You are using depends_on which wait until docker container status is not "up", but every service or program within this container can be "not finished" or in statuses like "run" or "up".
Check Controlling startup order in Compose I think it is exactly what you need.
Use a tool such as wait-for-it or dockerize. These are small wrapper scripts which you can include in your application’s image and will poll a given host and port until it’s accepting TCP connections. Supposing your application’s image has a CMD set in its Dockerfile, you can wrap it by setting the entrypoint in docker-compose.yml:
So you will need entrypoint that will wait after postgres port will be available and postgres in running status.
In docker-compose you will need for example
entrypoint: ./wait-for-it.sh db:5432
and in the script you will check every second whether postgres is running - docker container will be blocked until postgres is unavailable.
Like in documentation:
until psql -h "$host" -U "postgres" -c '\l'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
Solution 2:[2]
You can use depends_on with healthcheck if using compose v2.1+ (but not 3+ as it dropped condition https://github.com/peter-evans/docker-compose-healthcheck/issues/3)
Example, in a database container:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 30s
retries: 3
Project that depends on database:
depends_on:
kong-database:
condition: service_healthy
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Taylor D. Edmiston |
| Solution 2 |
