You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab CI/CD中Playwright容器无法访问Web服务容器的问题

GitLab CI/CD中Playwright容器无法访问Docker容器内Web服务的问题解决

问题场景与现象

在GitLab CI/CD流水线中,尝试使用Playwright容器测试运行在Docker容器中的Web服务,当前gitlab-ci.yml配置如下:

stages:
  - test
services:
  - docker:27-dind

variables:
  DOCKER_HOST: tcp://docker:2375/
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ""

container-tests:
  stage: test
  when: always
  image: docker:27
  script:
    - docker run -d --name app -p 8000:80 image-name
    - curl http://docker:8000 # 这可以正常访问!
    - >
      docker run --name tests -v "$(pwd)/tests:/tests" 
      mcr.microsoft.com/playwright/python:v1.50.0-noble /bin/sh -c "
      pip install pytest-base-url pytest-playwright playwright &&
      playwright install &&
      pytest /tests --base-url='http://docker:8000'"
    # 这无法正常工作!

现象:Web服务容器启动后,Job容器内用curl http://docker:8000可正常访问,但Playwright容器执行测试时,报错无法解析主机名:

except Exception as error:
>           raise rewrite_error(error, f"{parsed_st['apiName']}: {error}") from None
E           playwright._impl._errors.Error: Page.goto: net::ERR_NAME_NOT_RESOLVED at http://docker:8000/
E           Call log:
E             - navigating to "http://docker:8000/", waiting until "load"

核心问题分析

当前方案存在根本性错误:app容器与tests容器的网络环境不互通。

  • Job容器能访问http://docker:8000,是因为docker是GitLab CI服务的名称,Job容器的hosts文件已配置该名称指向dind服务的IP,且app容器把端口映射到了dind服务主机。
  • 但tests容器运行在dind服务的Docker环境中,其内部无法解析docker这个GitLab CI服务名称;同时两个容器默认处于同一bridge网络但未利用容器名通信,导致访问失败。

修正后的配置方案

1. 创建自定义Docker网络

先创建专属测试网络,确保容器间可通过名称直接通信:

docker network create test-network

2. 启动Web服务容器并加入自定义网络

修改app容器启动命令,加入自定义网络,保留端口映射以便Job容器验证:

docker run -d --name app --network test-network -p 8000:80 image-name

3. 启动Playwright容器并加入同一网络

修改tests容器启动命令,加入自定义网络,并直接用app容器名访问内部端口(无需依赖端口映射):

docker run --name tests --network test-network -v "$(pwd)/tests:/tests" \
mcr.microsoft.com/playwright/python:v1.50.0-noble /bin/sh -c "
pip install pytest-base-url pytest-playwright playwright &&
playwright install &&
pytest /tests --base-url='http://app:80'"

完整修正后的gitlab-ci.yml

stages:
  - test
services:
  - docker:27-dind

variables:
  DOCKER_HOST: tcp://docker:2375/
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ""

container-tests:
  stage: test
  when: always
  image: docker:27
  script:
    - docker network create test-network
    - docker run -d --name app --network test-network -p 8000:80 image-name
    # 轮询等待服务就绪,避免未启动完成就执行测试
    - until curl -s http://docker:8000; do sleep 2; done
    - >
      docker run --name tests --network test-network -v "$(pwd)/tests:/tests" 
      mcr.microsoft.com/playwright/python:v1.50.0-noble /bin/sh -c "
      pip install pytest-base-url pytest-playwright playwright &&
      playwright install &&
      pytest /tests --base-url='http://app:80'"
    # 清理资源
    - docker stop app tests
    - docker network rm test-network

最佳实践建议

  • 用自定义网络管理容器通信:避免默认bridge网络的限制,容器间通过名称直接访问,无需依赖端口映射或外部主机名。
  • 添加服务就绪检查:测试前通过轮询确保Web服务完全启动,避免因服务未就绪导致的测试失败。
  • 预构建Playwright自定义镜像:将依赖包、浏览器预安装到自定义镜像中,避免每次流水线重复安装,缩短执行时间。
  • 优先用GitLab CI Services启动服务:若Web服务可直接作为CI服务启动,无需手动docker run,服务会自动与Job容器处于同一网络,配置更简洁。
  • 清理流水线资源:在流水线结束后停止容器、删除网络,避免dind服务中残留无用资源。

内容的提问来源于stack exchange,提问作者Jasper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:53:14