Files
Genarrative/docs/technical/JENKINS_DEPLOY_ENV_BOM_FIX_2026-04-25.md
kdletters cbc27bad4a
Some checks failed
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

1.9 KiB
Raw Permalink Blame History

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.localBOM 会成为变量名前缀Bash 无法按赋值语句解析,进而把整行当作命令执行。日志末尾的 sudo 提示只是 hook 执行失败后的兜底提示,不是本次失败的真实根因。

2. 修复口径

  1. 发布包构建脚本复制 .env.env.local 到发布目录和 web/ 目录后,统一移除 UTF-8 BOM 与 CRLF。
  2. Jenkins 部署脚本在移动发布产物前后,再次净化发布目录和固定部署目录中的 .env.env.local,兼容已经构建出来但尚未部署成功的旧发布包。
  3. 新生成的 start.sh 不再直接 source 环境文件,而是按 KEY=value 子集解析、导出合法变量,并跳过空行、注释和不合法行。
  4. start.sh 仍保留 .env 先于 .env.local 的加载顺序,后加载的 .env.local 可以覆盖默认配置。

3. 运行边界

  1. 环境文件应保持 UTF-8 文本,允许 UTF-8 BOM 和 CRLF但部署脚本会在发布目录中消除它们。
  2. 环境变量名必须符合 [A-Za-z_][A-Za-z0-9_]*
  3. 值支持不加引号、双引号和单引号;复杂 shell 表达式不会执行,避免把环境文件变成脚本入口。
  4. 业务密钥仍通过目标服务器环境变量或发布目录 .env.local 管理,不写入 Jenkinsfile。

4. 失败现场恢复

如果 Jenkins 已经生成了失败版本,可以在拉取本次脚本修复后直接重跑部署流水线。scripts/jenkins-deploy-release.sh 会在执行新版本 start.sh 前净化已有发布目录,因此不要求手工编辑服务器上的 .env.local