m o*_*m o 38 docker docker-compose
泊坞窗,撰写2.1提供了很好的功能,以指定condition用depends_on.当前的docker-compose文档说明:
版本3不再支持depends_on的条件形式.
不幸的是,文档没有解释,为什么condition表单被删除,并且缺乏关于如何使用V3向上实现该行为的任何具体建议.
Jak*_*kul 16
有一些外部工具可以让您模仿这种行为。例如,使用dockerize 工具,您可以包装您的CMD或ENTRYPOINT,dockerize -wait这将阻止运行您的应用程序,直到指定的服务准备就绪。
如果您的 docker-compose 文件以前看起来像这样:
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
Run Code Online (Sandbox Code Playgroud)
然后你可以dockerize在你的v3撰写文件中使用这样的:
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
Run Code Online (Sandbox Code Playgroud)
Ber*_*ard 13
在compose中指定容器依赖关系已经有了一步之遥.它们仅在启动时有效,并且在运行时重新启动相关容器时不起作用.相反,每个容器应包括在删除连接时重试重新连接到从属服务的机制.许多连接到数据库或REST API服务的库都具有可配置的内置重试.我会调查一下.无论如何,生产代码都需要它.
qua*_*nta 11
从1.27.0 开始,2.x 和 3.x 与COMPOSE_SPEC架构合并。
services:
web:
build: .
depends_on:
redis:
condition: service_healthy
redis:
image: redis
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 1s
timeout: 3s
retries: 30
Run Code Online (Sandbox Code Playgroud)
只是想我会在通过 docker-compose 运行 postgres 和应用程序时添加我的解决方案,我需要应用程序在开始之前等待 init sql 脚本完成。
dockerize 似乎等待 db 端口可用(端口 5432),这是depends_on可以在 docker 3 中使用的等效端口:
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/
Run Code Online (Sandbox Code Playgroud)
问题:
如果您有一个大的 init 脚本,该应用程序将在该脚本完成之前启动,因为depends_on它只等待 db 端口。
尽管我确实同意应该在应用程序逻辑中实现解决方案,但我们遇到的问题仅适用于我们想要运行测试并使用测试数据预填充数据库时,因此像我倾向于的那样在代码之外实现解决方案更有意义不像引入代码“使测试工作”
解决方案:
对 postgres 容器实施健康检查。对我来说,这意味着检查 pid 1 的命令是postgres因为当 init db 脚本正在运行时它将在 pid 1 上运行不同的命令
在应用程序端编写一个脚本,等待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"
Run Code Online (Sandbox Code Playgroud)
然后 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11626 次 |
| 最近记录: |