1.9 KiB
1.9 KiB
Jenkins 部署环境文件 BOM 修复
日期:2026-04-25
1. 问题
Jenkins 部署阶段执行固定目录内的 start.sh 时失败:
/var/lib/jenkins/deploy/Genarrative/.env.local: line 1: VITE_LLM_BASE_URL=...: No such file or directory
根因是 .env.local 第一行包含 UTF-8 BOM。旧版 start.sh 直接 source .env.local,BOM 会成为变量名前缀,Bash 无法按赋值语句解析,进而把整行当作命令执行。日志末尾的 sudo 提示只是 hook 执行失败后的兜底提示,不是本次失败的真实根因。
2. 修复口径
- 发布包构建脚本复制
.env、.env.local到发布目录和web/目录后,统一移除 UTF-8 BOM 与 CRLF。 - Jenkins 部署脚本在移动发布产物前后,再次净化发布目录和固定部署目录中的
.env、.env.local,兼容已经构建出来但尚未部署成功的旧发布包。 - 新生成的
start.sh不再直接source环境文件,而是按KEY=value子集解析、导出合法变量,并跳过空行、注释和不合法行。 start.sh仍保留.env先于.env.local的加载顺序,后加载的.env.local可以覆盖默认配置。
3. 运行边界
- 环境文件应保持 UTF-8 文本,允许 UTF-8 BOM 和 CRLF,但部署脚本会在发布目录中消除它们。
- 环境变量名必须符合
[A-Za-z_][A-Za-z0-9_]*。 - 值支持不加引号、双引号和单引号;复杂 shell 表达式不会执行,避免把环境文件变成脚本入口。
- 业务密钥仍通过目标服务器环境变量或发布目录
.env.local管理,不写入 Jenkinsfile。
4. 失败现场恢复
如果 Jenkins 已经生成了失败版本,可以在拉取本次脚本修复后直接重跑部署流水线。scripts/jenkins-deploy-release.sh 会在执行新版本 start.sh 前净化已有发布目录,因此不要求手工编辑服务器上的 .env.local。