docker-compose 2.1提供了用depends_on指定condition的好特性。版本3不再支持depends_on的条件形式。不幸的是,文档没有解释为什么condition表单被删除,也没有任何关于如何使用V3以上版本实现该行为的具体建议。
depends_on
condition
0yg35tkg1#
在composition中不再指定容器依赖项。它们只在启动时有效,并且在依赖容器在运行时重新启动时不起作用。每个容器都应该包含一个机制,当连接断开时,重试重新连接到依赖的服务。许多连接到数据库或API服务的库都有可配置的内置重试。我会研究这个问题。无论如何,生产代码都需要它。
7xllpg7q2#
在1.27.0中,2.x和3.x与COMPOSE_SPEC架构合并。version现在是可选的。因此,您只需删除它并像以前一样指定一个条件:
services: web: build: . depends_on: redis: condition: service_healthy redis: image: redis healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 1s timeout: 3s retries: 30
zaqlnxep3#
有一些外部工具可以让你模仿这种行为,例如,使用dockerize工具,你可以用dockerize -wait来 Package 你的CMD或ENTRYPOINT,这将阻止你的应用程序运行,直到指定的服务准备就绪。如果您的Docker合成文件过去是这样的:
dockerize -wait
CMD
ENTRYPOINT
version: '2.1' services: kafka: image: spotify/kafka healthcheck: test: nc -z localhost 9092 webapp: image: foo/bar # your image healthcheck: test: curl -f http://localhost:8080 tests: image: bar/foo # your image command: YOUR_TEST_COMMAND depends_on: kafka: condition: service_healthy webapp: condition: service_healthy
然后你可以在你的v3合成文件中使用dockerize,如下所示:
v3
dockerize
version: '3.0' services: kafka: image: spotify/kafka webapp: image: foo/bar # your image tests: image: bar/foo # your image command: dockerize -wait tcp://kafka:9092 -wait web://webapp:8080 YOUR_TEST_COMMAND
c6ubokkw4#
我只是想添加我的解决方案,当运行postgres和一个应用程序通过docker-compose,我需要应用程序等待init sql脚本完成,然后再开始。dockerize似乎在等待db端口可用(端口5432),这与可以在docker 3中使用的depends_on是等价的:
version: '3' services: app: container_name: back-end depends_on: - postgres postgres: image: postgres:10-alpine container_name: postgres ports: - "5432:5432" volumes: - ./docker-init:/docker-entrypoint-initdb.d/
问题:
如果您有一个很大的init脚本,则应用程序将在其完成之前启动,因为depends_on只等待db端口。虽然我同意解决方案应该在应用程序逻辑中实现,但我们遇到的问题只是当我们想要运行测试并使用测试数据预填充数据库时,因此在代码之外实现解决方案更有意义,因为我不喜欢引入代码“使测试工作”
解决方案:
在postgres容器上实现健康检查。对我来说,这意味着检查pid 1的命令是否为postgres,因为当init db脚本运行时,它将在pid 1上运行不同的命令在应用程序端编写一个脚本,等待postgres变为healthy。脚本如下所示:
postgres
healthy
#!/bin/bash function check { STATUS=\`curl -s --unix-socket /var/run/docker.sock http:/v1.24/containers/postgres/json | python -c 'import sys, json; print json.load('sys.stdin')["State"]["Health"]["Status"]'\` if [ "$STATUS" = "healthy" ]; then return 0 fi return 1 } until check; do echo "Waiting for postgres to be ready" sleep 5 done echo "Postgres ready"
然后docker-compose应该挂载脚本的目录,这样我们就不会编辑应用程序的Dockerfile,如果我们使用的是自定义的postgres映像,这样我们就可以继续为您发布的映像使用docker文件。我们还覆盖了应用程序的docker文件中定义的入口点,以便可以在应用程序启动之前运行等待脚本
version: '3' services: app: container_name: back-end entrypoint: ["/bin/sh","-c","/opt/app/wait/wait-for-postgres.sh && <YOUR_APP_START_SCRIPT>"] depends_on: - postgres volumes: - //var/run/docker.sock:/var/run/docker.sock - ./docker-scripts/wait-for-postgres:/opt/app/wait postgres: image: postgres:10-alpine container_name: postgres ports: - "5432:5432" volumes: - ./docker-init:/docker-entrypoint-initdb.d/ - ./docker-scripts/postgres-healthcheck:/var/lib healthcheck: test: /var/lib/healthcheck.sh interval: 5s timeout: 5s retries: 10
j2cgzkjk5#
我到达此页是因为一个容器不等待依赖的容器,我必须运行docker system prune才能使其工作。出现orphaned container错误,提示我运行prune。
docker system prune
orphaned container
prune
628mspwn6#
如果有人正在寻找这个的docker stack版本:它看起来像它是目前不可能定义的依赖关系时使用Docker堆栈:https://github.com/docker/cli/issues/3880
docker stack
6条答案
按热度按时间0yg35tkg1#
在composition中不再指定容器依赖项。它们只在启动时有效,并且在依赖容器在运行时重新启动时不起作用。每个容器都应该包含一个机制,当连接断开时,重试重新连接到依赖的服务。许多连接到数据库或API服务的库都有可配置的内置重试。我会研究这个问题。无论如何,生产代码都需要它。
7xllpg7q2#
在1.27.0中,2.x和3.x与COMPOSE_SPEC架构合并。
version现在是可选的。因此,您只需删除它并像以前一样指定一个条件:
zaqlnxep3#
有一些外部工具可以让你模仿这种行为,例如,使用dockerize工具,你可以用
dockerize -wait
来 Package 你的CMD
或ENTRYPOINT
,这将阻止你的应用程序运行,直到指定的服务准备就绪。如果您的Docker合成文件过去是这样的:
然后你可以在你的
v3
合成文件中使用dockerize
,如下所示:c6ubokkw4#
我只是想添加我的解决方案,当运行postgres和一个应用程序通过docker-compose,我需要应用程序等待init sql脚本完成,然后再开始。
dockerize似乎在等待db端口可用(端口5432),这与可以在docker 3中使用的
depends_on
是等价的:问题:
如果您有一个很大的init脚本,则应用程序将在其完成之前启动,因为
depends_on
只等待db端口。虽然我同意解决方案应该在应用程序逻辑中实现,但我们遇到的问题只是当我们想要运行测试并使用测试数据预填充数据库时,因此在代码之外实现解决方案更有意义,因为我不喜欢引入代码“使测试工作”
解决方案:
在postgres容器上实现健康检查。对我来说,这意味着检查pid 1的命令是否为
postgres
,因为当init db脚本运行时,它将在pid 1上运行不同的命令在应用程序端编写一个脚本,等待
postgres
变为healthy
。脚本如下所示:然后docker-compose应该挂载脚本的目录,这样我们就不会编辑应用程序的Dockerfile,如果我们使用的是自定义的postgres映像,这样我们就可以继续为您发布的映像使用docker文件。
我们还覆盖了应用程序的docker文件中定义的入口点,以便可以在应用程序启动之前运行等待脚本
j2cgzkjk5#
我到达此页是因为一个容器不等待依赖的容器,我必须运行
docker system prune
才能使其工作。出现orphaned container
错误,提示我运行prune
。628mspwn6#
如果有人正在寻找这个的
docker stack
版本:它看起来像它是目前不可能定义的依赖关系时使用Docker堆栈:https://github.com/docker/cli/issues/3880