Jenkins构建Laravel项目读取旧.env DB_HOST值致连接超时如何解决
问题根因
该问题和AWS侧网络无关(手动执行迁移成功已经证明EC2到RDS的连通性正常),核心是三个配置/逻辑错误:
- 目录隔离:Jenkins流水线执行时会使用独立的工作空间目录(默认路径为
/var/lib/jenkins/workspace/<你的流水线名称>),和登录终端手动操作的项目目录不是同一个路径,在终端手动修改.env、清理缓存的操作完全不会作用于Jenkins的执行环境。 - Sed语法错误:原有DB_HOST替换规则
sed -i 's|^DB_HOST=.*|&${DB_HOST}|' .env存在逻辑错误,&在sed替换语法中代表匹配到的完整原字符串,该命令实际效果是在旧的DB_HOST值后面拼接新的DB_HOST值,而非替换旧值,生成的配置本身就是错误的。 - 缓存未在流水线内清理:原有流程没有在Jenkins执行步骤中清理Laravel的配置缓存,即使.env写入正确,Laravel也会读取之前构建生成的固化配置文件,不会加载新的.env内容。
修复方案
按以下顺序调整流水线配置即可解决问题:
- 修正DB_HOST的sed替换语法,把追加逻辑改为整行替换
- 在执行数据库操作前,在流水线步骤内显式清理所有Laravel缓存,重新加载配置
- 增加配置校验步骤,确认.env写入结果符合预期
- 可选:构建前清空工作空间,彻底避免历史残留文件干扰
修正后的完整Unit test阶段代码如下:
stage("Unit test") { steps { // 可选:打开注释即可在每次构建前清空当前工作空间旧文件,避免脏数据影响 // deleteDir() sh "sed -i -e 's/\r//g' .env.example" sh 'cp .env.example .env' // 修正所有sed替换逻辑,直接替换整行而非追加 sh "sed -i 's/^DB_DATABASE=.*/DB_DATABASE=${DB_DATABASE}/' .env" sh "sed -i 's/^DB_USERNAME=.*/DB_USERNAME=${DB_USERNAME}/' .env" sh "sed -i 's|^DB_HOST=.*|DB_HOST=${DB_HOST}|' .env" sh script: $/ sed -i 's/^\(DB_PASSWORD=*\).*$/\1"${DB_PASSWORD}"/' .env sed -i 's/^\(APP_ENV=*\).*$/\1"testing"/' .env /$ // 打印DB配置校验写入结果,构建日志里可以直接看到实际加载的配置 sh 'grep ^DB_ .env' // 流水线内清理所有Laravel缓存,必须执行,不要依赖外部手动操作 sh 'php artisan config:clear' sh 'php artisan cache:clear' sh 'php artisan route:clear' sh 'php artisan view:clear' // 重新生成配置缓存,确保加载最新的.env值 sh 'php artisan config:cache' sh 'php artisan migrate' sh 'php artisan test' } }
注意:如果开启了Jenkins的并行构建,或者之前有失败构建残留了异常配置文件,建议把
deleteDir()步骤的注释打开,每次构建前清空工作空间重新拉取代码,可以彻底规避旧文件导致的各类异常。
内容的提问来源于stack exchange,提问作者Kinshuk Lahiri
相关产品推荐
相关产品推荐

