docker - 如何在 Docker Compose 中让容器等待其他容器

标签 docker deployment configuration containers docker-compose

我正在关注this教程并尝试使用 Docker Compose 来启动基础设施,而不是调用 docker 客户端的 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"

最佳答案

gitlab container is started before gitlab-postgreql and gitlab-redis,

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

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

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:

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

在脚本中,您将每秒检查 postgres 是否正在运行 - docker 容器将被阻止,直到 postgres 不可用。

如文档中所示:

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

关于docker - 如何在 Docker Compose 中让容器等待其他容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40202861/

相关文章:

javascript - 如何将 Web 应用程序部署到现有域 Meteor javascript

android - Android Gradle Build Variant Deploy

configuration - 如何将我的配置添加到 Sublime Text 2 的菜单?

.net - 在 WCF 中相对于工作目录加载自定义配置文件

ruby - ruby docker 图像中的过期 ca 证书(2.6.8-bullseye)

docker - 打印在Docker容器中运行的Shell脚本的输出

ruby-on-rails - 出现 asset not present in asset pipeline 错误后,无法将我的 Rails 应用程序部署到 heroku

git - Netbeans 中缺少(明显)Git 按钮

docker - gitlab ci 无法构建 windows 容器

docker - 主机上Docker容器的文件系统内容