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

Tuo*_*nen 3 deployment configuration containers docker docker-compose

我正在按照教程尝试使用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"
Run Code Online (Sandbox Code Playgroud)

Vla*_*cak 7

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

您正在使用depends_on哪个等待,直到docker容器状态不是"up",但此容器中的每个服务或程序都可能"未完成"或状态如"run"或"up".

检查Compose中的控制启动顺序我认为这正是您所需要的.

使用wait-for-it或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
Run Code Online (Sandbox Code Playgroud)