我正在使用docker compose来运行几个相互依赖的服务。这是 docker 编写的一部分:
backend:
build: .
command: bash -c "npm run build && npm start"
ports:
- "3015:3015"
depends_on:
- couchdb
- redis
- uds-mock-server
volumes:
- /app/node_modules
- .:/app
user: root
api-test:
restart: always
build: .
depends_on:
- backend
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3015/readiness"]
interval: 200s
timeout: 200s
retries: 5
user: root
如您所见,我在那里有两个服务,后端应该首先运行并且服务器需要准备就绪,然后 api 测试可以启动。 后端有一个端点:localhost:2015/readiness 每当它返回 200 时,API 测试就可以启动。当我在构建订单时运行时,首先是后端,然后是 api-mock,但是当 docker compose 开始运行时,它们的 api 测试运行速度更快,并且由于它依赖于后端准备就绪,因此会失败。
基于以下内容:
Docker Compose 在启动 Y 之前等待容器 X
和
作曲家文件中的 Docker 运行状况检查
建议我应该使用我在 api 测试中所做的健康检查:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3015/readiness"]
interval: 200s
timeout: 200s
retries: 5
如果我得到正确,api-test 应该运行并调用就绪端点并等待它听到后端准备(最多 200 秒(,如果它失败,它会等待 200 秒,然后重试 5 次。 但是我看到的是 api-test 不断失败并重新启动,甚至没有给后端运行的机会,它一直像循环一样这样做。 我错过了什么吗?任何帮助都非常感谢
这两个示例基于condition
形式的depends_on
,该形式在撰写版本 3 中不再受支持。因此,除非您的 docker-compose 版本是 <3,否则healthcheck
不会对您有很大帮助。healthcheck
设置容器的状态(正在启动、正常或不正常(,但docker-compose
不会等到容器backend
正常后再启动app-test
。在撰写中的控制启动和关闭顺序中,有关于depends_on
如何工作的详细说明
作为旁注,撰写文件中的运行状况检查设置app-test
容器的状态,而不是backend
。
因此,若要控制api-test
何时可以启动,必须包装容器的服务命令。对于您的特定情况,以下内容将完成这项工作:
bash -c 'while [[ "$(curl --connect-timeout 2 -s -o /dev/null -w ''%{http_code}'' https://backend:3015/readiness)" != "200" ]]; do echo ..; sleep 5; done; echo backend is up; <service_command>'
它每 5 秒尝试连接到backend
(连接超时为 2 秒(。当收到的 HTTP 状态代码为 200 OK 时,循环结束并执行<service_command>
相关的 docker 组成部分:
api-test:
restart: always
command: bash -c 'while [[ "$$(curl --connect-timeout 2 -s -o /dev/null -w ''%{http_code}'' uds-mock-server:4000/readiness)" != "200" ]]; do echo ..; sleep 5; done; echo backend is up;npm start'
depends_on:
- backend
...
希望这有帮助。
它不是localhost
连接字符串。
它应该是后端容器的服务名称:
test: ["CMD", "curl", "-f", "http://backend:3015/readiness"]
如果您使用的是最新的Docker桌面(在Windows上测试过版本4.14.0(,则将depends_on与condition: service_healthy
一起使用。 例:
depends_on:
oracle:
condition: service_healthy
注意:撰写的版本令人困惑。 多年来,docker-compose
变得docker compose
并引入了具有重叠版本号的替代实现。 Docker Desktop 附带的版本现在似乎称为 docker compose V2,您可以在 docker-compose.yml 文件中通过不包含任何版本号来指示它。 这与旧的 docker-compose V2 不同,如果 YAML 文件中未指定版本,则实际上默认为 docker-compose V1。