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

时间:2016-10-23 12:25:00

标签: docker deployment configuration containers docker-compose

我正在关注this教程并尝试使用Docker Compose而不是调用docker client的shell脚本来启动基础结构。一切正常,除了gitlab容器在gitlab-postgreql和gitlab-redis之前启动,因此失败,因为它预计这些服务已经在运行。

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

这怎么可能?我无法相信这样的基本功能尚未实现。看起来Docker正在绊倒它自己的聪明才智并忘记了基础知识。现在,如何在没有一些疯狂的支持脚本的情况下控制容器创建顺序(这会使整个配置变得更混乱,而不仅仅是首先使用脚本/ 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"

2 个答案:

答案 0 :(得分:7)

  

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

您正在使用depends_on等待,直到码头集装箱状态不是“向上”,但此容器中的每个服务或程序都可能“未完成”或状态如“运行”或“向上”。< / p>

检查Controlling startup order in Compose我认为这正是您所需要的。

  

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

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

在脚本中你将检查postgre是否正在运行 - 在postgre不可用之前,docker容器将被阻止。

与文档类似:​​

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

答案 1 :(得分:1)

如果使用撰写v2.1 +(但删除后不是3+ depends_on https://github.com/peter-evans/docker-compose-healthcheck/issues/3),则可以healthcheck使用condition

Example on GitHub

示例,在数据库容器中:

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

依赖于数据库的项目:

depends_on:
  kong-database:
    condition: service_healthy