如何强制 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_oncondition.

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)可以检测到服务不健康。