如何强制 docker-compose 中的等待脚本在后台工作?

krz*_*rzk 2 docker docker-compose cypress

我有一个包含以下服务的 docker-compose 文件:

  • 后端
  • 数据库
  • 前端
  • 数据库迁移
  • 柏树(E2E 测试)

我遇到的问题是当我运行时docker-compose up,第一个启动的服务是cypress.

Cypress 立即尝试到达backend并失败,并给出错误:

  > http://backend:8000
We are verifying this server because it has been configured as your `baseUrl`.
Cypress automatically waits until your server is accessible before running tests.
We will try connecting to it 3 more times...
We will try connecting to it 2 more times...
We will try connecting to it 1 more time...
Cypress failed to verify that your server is running.
Please start this server and then run Cypress again.
Run Code Online (Sandbox Code Playgroud)

然后,Cypress 服务退出,所有其他服务启动。

我一直在尝试强制赛普拉斯等待其他服务准备好,使用:

但这些脚本都没有按照我的预期工作。

预期行为:

  1. Cypress启动,触发等待脚本
  2. 所有其他服务在后台启动
  3. 等待脚本检测到服务已准备好,运行 cypress 测试

实际行为:

  1. Cypress启动,触发等待脚本
  2. wait-for 脚本阻塞线程,尝试到达 ie,backend直到达到超时
  3. 赛普拉斯服务失败
  4. 所有其他服务启动

我看不出我的设置有什么问题,但我敢打赌这不是这些wait-for脚本应该如何工作的。

有谁知道我该如何改变行为以满足期望?

以下是我的设置wait-on

  > http://backend:8000
We are verifying this server because it has been configured as your `baseUrl`.
Cypress automatically waits until your server is accessible before running tests.
We will try connecting to it 3 more times...
We will try connecting to it 2 more times...
We will try connecting to it 1 more time...
Cypress failed to verify that your server is running.
Please start this server and then run Cypress again.
Run Code Online (Sandbox Code Playgroud)

我已将 CI 配置为调用yarn test我已配置为的命令package.json:

version: "3.7"
x-backend-base: &backend_base
  env_file: .env
  build:
    context: ./backend/
    dockerfile: ./compose/backend/Dockerfile
  depends_on:
    - db

[...]

services:
  db:
    image: postgres:9.6-alpine

  backend:
    <<: *backend_base
    command: python manage.py runserver 0.0.0.0:8000

  cypress:
    build:
      context: .
      dockerfile: ./docker/cypress/Dockerfile
    entrypoint: tail -f /dev/null
    environment:
      CYPRESS_BASE_URL: http://backend:8000

[...]

Run Code Online (Sandbox Code Playgroud)

使用docker-compose-wait脚本的设置:

package.json:

"test": "wait-on --delay 3000 --timeout 180000 http://backend:8000/login/ && cypress run",
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml

"test": "/wait && cypress run",
Run Code Online (Sandbox Code Playgroud)

日志:

Executing yarn test on cypress service
yarn run v1.22.17
$ /wait && cypress run
[INFO  wait] --------------------------------------------------------
[INFO  wait]  docker-compose-wait 2.9.0
[INFO  wait] ---------------------------
[DEBUG wait] Starting with configuration:
[DEBUG wait]  - Hosts to be waiting for: [backend:8000]
[...]
[DEBUG wait] --------------------------------------------------------
[INFO  wait] Host [backend:8000] not yet available...
[...]
[INFO  wait] Host [backend:8000] not yet available...

[ERROR wait] Timeout! After 45 seconds some hosts are still not reachable
error Command failed with exit code 1.
Run Code Online (Sandbox Code Playgroud)

我得到的同样的行为wait-for-it.sh

我可以确认 CypressbaseUrl是正确的 - 有时当我在 CI 上重试失败的作业时,应用程序服务加载速度更快,然后 Cypress 测试通过。

The*_*ool 5

您可以depends_on与condition.

services:
  backend:
    health_check: curl -fsS localhost:8080/ping || exit 1

  cypress:
    depends_on:
      backend:
        condition: service_healthy
Run Code Online (Sandbox Code Playgroud)

使用数组语法的条件可能就足够了,service_started该条件相当于依赖于但没有条件。

有些人还以残酷的方式重新开始,直到成功。

services:
  cypress:
    deploy:
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 10
Run Code Online (Sandbox Code Playgroud)

就我个人而言,我认为即使给定的依赖项未启动,您的服务也能够启动是最好的。他们可以使用指数退避重试连接,直到成功为止,对于需要此依赖性的端点,以 503 之类的内容进行响应。

此外,检查就绪端点中与所述依赖项的连接。在这种情况下,某些操作框架(例如 Kubernetes)可以检测到服务不健康。