GitLab CI/CD连接MySQL报错ERROR 2005排查与修复求助
GitLab Runner CI/CD流水线MySQL连接失败问题分析与修复方案
问题场景
在Digital Ocean Droplet的自托管GitLab Runner中配置Laravel单元测试CI/CD流水线,依赖MySQL数据库支撑测试运行,但流水线执行失败,报错信息:
ERROR 2005 (HY000): Unknown server host 'mysql' (-3)
使用的CI/CD配置如下:
stages: - build - test image: ahmed2zaky2/laravel-deploy-php81:latest cache: key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" build: stage: build script: - apk update && apk add zip - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer - composer install --prefer-dist --no-ansi --no-interaction --no-progress --no-scripts - cp .env.testing.example .env.testing - cp .env.testing .env - php artisan key:generate - php artisan key:generate --env=testing - php artisan optimize - php artisan cache:clear - chmod 755 -R storage bootstrap/cache artifacts: paths: - vendor/ - .env - .env.testing cache: paths: - vendor/ only: - merge_requests - dev - main test-unit: stage: test services: - name: mysql:8.0 alias: mysql command: ["--default-authentication-plugin=mysql_native_password"] before_script: - mysql --version - sleep 30 - echo "SELECT 'OK';" | mysql -h$DB_HOST -u$MYSQL_USER -p$MYSQL_ROOT_PASSWORD -e "CREATE DATABASE ${MYSQL_DATABASE};" script: - php artisan test variables: MYSQL_ROOT_PASSWORD: root MYSQL_USER: root MYSQL_PASSWORD: root MYSQL_DATABASE: jadwalh_test MYSQL_HOST: mysql DB_HOST: mysql dependencies: - build environment: name: development only: - dev
流水线失败报错截图:
报错原因分析
- Runner执行器类型不匹配:
services是GitLab Runner Docker执行器的专属特性,如果自托管Runner配置的是shell或其他非Docker执行器,系统不会启动MySQL服务容器,自然无法解析mysql主机名。 - 容器网络DNS解析异常:即使使用Docker执行器,自托管环境的Docker网络配置错误(如自定义网络未创建、DNS服务不可用),会导致Job容器无法通过别名
mysql解析到MySQL容器。 - .env文件配置未被覆盖:Build阶段生成的
.env/.env.testing文件中可能硬编码了DB_HOST值(如127.0.0.1),Test阶段的环境变量无法覆盖文件配置,导致Laravel连接错误主机。 - MySQL服务未完全就绪:固定30秒的
sleep无法保证MySQL完成初始化,提前执行连接命令会导致主机解析或连接失败。
修复方案
1. 调整GitLab Runner执行器配置
检查自托管Runner的config.toml文件(通常在/etc/gitlab-runner/目录),确保执行器设置为docker:
[[runners]] name = "your-runner-name" url = "https://gitlab.com/" token = "your-runner-token" executor = "docker" [runners.docker] tls_verify = false image = "docker:latest" privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["/cache"] shm_size = 0 [runners.cache] [runners.cache.s3] [runners.cache.gcs]
修改后重启Runner服务:sudo gitlab-runner restart
2. 替换固定等待为MySQL就绪检测脚本
将before_script中的sleep 30替换为可靠的就绪检测逻辑,确保MySQL完全启动后再执行命令:
- until mysql -h$DB_HOST -u$MYSQL_USER -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do echo "Waiting for MySQL..."; sleep 5; done
3. 强制覆盖.env文件数据库配置
在Test阶段的before_script中添加命令,强制替换.env/.env.testing中的数据库配置:
- sed -i "s/DB_HOST=.*/DB_HOST=$DB_HOST/" .env - sed -i "s/DB_HOST=.*/DB_HOST=$DB_HOST/" .env.testing - sed -i "s/DB_DATABASE=.*/DB_DATABASE=$MYSQL_DATABASE/" .env - sed -i "s/DB_DATABASE=.*/DB_DATABASE=$MYSQL_DATABASE/" .env.testing - sed -i "s/DB_USERNAME=.*/DB_USERNAME=$MYSQL_USER/" .env - sed -i "s/DB_USERNAME=.*/DB_USERNAME=$MYSQL_USER/" .env.testing - sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=$MYSQL_PASSWORD/" .env - sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=$MYSQL_PASSWORD/" .env.testing
4. 验证容器网络连通性
在Test阶段的before_script中添加网络检测命令,排查DNS解析问题:
- ping -c 3 mysql - nc -zv mysql 3306
如果ping不通,检查Docker网络配置,确保Runner使用默认桥接网络或正确的自定义网络。
5. 优化MySQL服务配置(可选)
为MySQL 8.0添加环境变量避免权限问题,修改services部分:
services: - name: mysql:8.0 alias: mysql command: ["--default-authentication-plugin=mysql_native_password"] variables: MYSQL_ALLOW_EMPTY_PASSWORD: "no"
内容的提问来源于stack exchange,提问作者ahmed
相关产品推荐
相关产品推荐



