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

GitLab CI中以容器为服务运行时出现SQLSTATE[HY000] [2002]错误求助

问题描述

在GitLab CI中使用Playwright执行端到端测试时,已通过前置任务构建好应用Docker容器,并在e2e测试任务中配置为服务,但应用无法连接数据库,报错:

SQLSTATE[HY000] [2002] No such file or directory

当前CI配置如下:

e2e_tests:
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
    - if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH)
  stage:
    e2e_test
  needs:
    - build_api_dev
    - build_frontend_dev
  image:
    name: mcr.microsoft.com/playwright:v1.47.2-noble
  services:
    - name: mysql:8.0.32
      alias: database
    - name: schickling/mailcatcher
      alias: mailcatcher
    - name: $CI_REGISTRY_IMAGE:api-dev-$CI_COMMIT_SHA
      alias: api
    - name: $CI_REGISTRY_IMAGE:api-nginx-dev-$CI_COMMIT_SHA
      alias: nginx
    - name: $CI_REGISTRY_IMAGE:frontend-dev-$CI_COMMIT_SHA
      alias: frontend
  variables:
    MYSQL_DATABASE_NAME: symfony
    MYSQL_ROOT_PASSWORD: root
    MYSQL_USER: symfony
    MYSQL_PASSWORD: symfony
    MYSQL_DATABASE: symfony_test
    DB_HOST: localhost
    DB_USER: $MYSQL_ROOT_PASSWORD
    DB_PASSWORD: $MYSQL_ROOT_PASSWORD
    DB_DATABASE: $MYSQL_DATABASE
    FRONTEND_URL: http://localhost:3000
    REACT_APP_PUBLIC_API_URL: http://localhost
  script:
    - mysql -h database -u root -proot <<< "SET GLOBAL sql_mode = '';"
    - mysql -h database -u root -proot symfony < db/dump-latest.sql
    - cd e2e
    - npm install
    - npm run test
  artifacts:
    name: "e2e-tests Report $CI_MERGE_REQUEST_TITLE"
    paths:
      - e2e/playwright-report/
    expire_in: 1 week

本地使用docker-compose运行相同镜像时一切正常。

解决方案

1. 修正数据库主机配置

GitLab CI中,服务容器(如mysql)与主任务容器通过内部网络通信,不能用localhost访问服务容器,必须使用服务配置中指定的alias(此处为database)作为主机地址。

修改变量中的DB_HOST:

DB_HOST: database

2. 修正数据库用户变量

当前DB_USER错误引用了$MYSQL_ROOT_PASSWORD(虽值为root但逻辑错误),直接改为root或正确引用用户变量:

# 使用root用户
DB_USER: root
# 或使用普通用户symfony
DB_USER: $MYSQL_USER

同时DB_PASSWORD需对应调整:用root用户则设为$MYSQL_ROOT_PASSWORD,用普通用户则设为$MYSQL_PASSWORD。

3. 添加数据库就绪等待(可选但推荐)

MySQL容器启动后需要时间完成初始化,主任务直接执行SQL命令可能连接失败,可在脚本开头添加等待逻辑:

# 等待MySQL服务就绪
until mysql -h database -u root -proot -e "SELECT 1"; do
  echo "等待MySQL启动..."
  sleep 2
done

修改后的核心配置示例

variables:
  MYSQL_DATABASE_NAME: symfony
  MYSQL_ROOT_PASSWORD: root
  MYSQL_USER: symfony
  MYSQL_PASSWORD: symfony
  MYSQL_DATABASE: symfony_test
  DB_HOST: database
  DB_USER: root
  DB_PASSWORD: $MYSQL_ROOT_PASSWORD
  DB_DATABASE: $MYSQL_DATABASE
  FRONTEND_URL: http://localhost:3000
  REACT_APP_PUBLIC_API_URL: http://localhost

script:
  - until mysql -h database -u root -proot -e "SELECT 1"; do echo "等待MySQL启动..."; sleep 2; done
  - mysql -h database -u root -proot <<< "SET GLOBAL sql_mode = '';"
  - mysql -h database -u root -proot symfony < db/dump-latest.sql
  - cd e2e
  - npm install
  - npm run test

额外检查点

  • 确认API容器(api)能正确读取环境变量,确保它连接的是database主机而非localhost。
  • 本地docker-compose通过端口映射让localhost能访问MySQL,但GitLab CI网络模型不同,必须用服务别名通信。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 16:03:14