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
相关产品推荐
相关产品推荐

