如何使容器在Docker Compose中等待其他容器

我正在学习本教程,尝试使用Docker Compose来启动基础架构,而不是调用docker客户端的shell脚本。 一切工作正常,除了gitlab容器之前启动gitlab-postgreql和gitlab-redis,从而失败,因为它预计这些服务已经运行。

我试图使用depends_on属性,但它没有解决问题。 据我所知,如果其他容器的启动速度更快,这也无济于事。 经过一番研究,我发现,Docker Compose不提供开箱即用的解决scheme来控制容器的创build顺序。

怎么会这样? 我不敢相信这样的一个基本特征没有实现。 似乎Docker正在绊倒它自己的聪明之处,忘记了基础知识。 现在,我如何控制容器创build顺序,而不需要一些疯狂的支持脚本(这将使整个configuration比首先使用脚本/ docker客户端更复杂)

这是docker-compose.yml,因为它是

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" 

gitlab容器在gitlab-postgreql和gitlab-redis之前启动,

您正在使用depends_on ,它等待depends_on容器状态不是“up”,但是此容器中的每个服务或程序都可能“未完成”,或处于“run”或“up”状态。

检查控制Compose中的启动顺序我认为这正是你需要的。

使用等待或dockerize等工具。 这些小包装脚本可以包含在应用程序的映像中,并轮询给定的主机和端口,直到它接受TCP连接。 假设您的应用程序的图像在其Dockerfile中设置了CMD,则可以通过在docker-compose.yml中设置入口点来封装它:

所以你需要在postgres端口可用和postgre处于运行状态之后等待的入口点。 在docker-compose中,您将需要例如entrypoint: ./wait-for-it.sh db:5432

在脚本中你会检查每一秒postgre是否正在运行 – docker容器将被阻止,直到postgre不可用。

像在文档中一样:

 until psql -h "$host" -U "postgres" -c '\l'; do >&2 echo "Postgres is unavailable - sleeping" sleep 1 done