6.8 KiB
Jenkins 灰度部署
现有灰度环境使用 Jenkinsfile、Dockerfile 和 deploy/ 发布独立物流聊天服务。流水线构建并测试镜像,通过严格校验主机指纹的 SSH 发送到专用 Docker Compose 服务,Nginx 提供 HTTPS 和全站访问密码。
应用使用单个 Waitress 进程、8 个线程和 UID 10001,宿主机端口仅绑定回环地址。运行密钥、聊天数据、附件和证书不进入镜像。后台鉴权与会话隔离仍不完整,灰度验收须保留全站密码;此流程不代表已具备面向多个客户开放的权限体系。
容器时区设为 Asia/Shanghai,营业时间与聊天时间按中国时间计算。
Jenkins 任务
任务名为 baiyue-logistics-chat-gray。定义选择 Pipeline script from SCM,本项目 Git 地址为仓库,分支字段为 ${SOURCE_REF},脚本路径为 Jenkinsfile。公开仓库可匿名读取;转为私有后配置只读 SCM 凭据。
java-builder 标签代理须有 Docker、Bash、Python 3、Node.js 18+、OpenSSL、SSH,并能下载所选 Python 基础镜像和 PyPI 依赖。标签不表示固定物理节点。
以下参数由私有灰度配置提供,实际地址和凭据值不写入源码:
| 参数 | 含义 |
|---|---|
ENVIRONMENT |
单选 gray,流水线拒绝其他值 |
SOURCE_REF |
本次发布的不可变标签或提交,也可明确选择开发分支 |
PYTHON_BASE_IMAGE |
已验证的官方 Python 3.12 基础镜像 |
PUBLIC_ORIGIN |
独立 HTTPS 域名,不带子路径 |
HOST_PORT |
已确认空闲的宿主机回环端口,如 29013 |
GRAY_DEPLOY_DIR |
专用目录,末级必须为 gray-logistics-chat |
GRAY_PROXY_CONF_DIR |
宿主机 Nginx 实际加载的站点目录 |
GRAY_TLS_CERT_FILE / GRAY_TLS_KEY_FILE |
本服务独立证书和私钥路径 |
SSH_CREDENTIAL_ID |
SSH 用户与私钥凭据引用 |
SSH_HOST_CREDENTIAL_ID |
SSH 目标的 Secret text 引用 |
SSH_KNOWN_HOSTS_CREDENTIAL_ID |
已核实的 known_hosts 文件引用 |
DEEPSEEK_CREDENTIAL_ID |
本服务模型密钥的 Secret text 引用 |
PREVIEW_AUTH_CREDENTIAL_ID |
专用验收用户名和密码引用 |
运行密钥和验收账号保存在私有灰度配置与 Jenkins 凭据库,供后续发布持续复用;轮换时同步更新。不要将密钥放在构建参数、Git URL、镜像 ARG、日志或示例文件中。
发布步骤
- 完成检查并提交代码,创建
gray-chat-YYYYMMDD-<commit12>一类不可变发布标签。不要重写已有标签或强推覆盖远端分支;分支有其他更新时先明确发布基线。 - 推送标签,在任务
SOURCE_REF选择该标签。Jenkins 按此引用加载流水线并检出代码,镜像记录完整提交 SHA。 - 流水线检查 Bash 语法,运行 Node 回归,再构建
test目标执行 Python 回归;通过后构建production应用镜像及certbot运维镜像。 - 构建完成后才绑定运行凭据。发布脚本校验路径、域名和源提交,生成私有配置并发送镜像及发布文件。服务器验证镜像归档的 SHA-256 后加载,记录目标主机的镜像 ID。
- 首次签发域名证书,等待应用健康,再安装本服务的 Nginx 配置。已有业务的容器和站点配置不参与本次发布。
- Jenkins 使用验收账号验证公网 HTTPS
/healthz;之后在浏览器验证 AI 流式回复、上传、转人工和工作台。
应用镜像必须选择 production 构建目标;certbot 仅用于证书运维。每个构建生成独立镜像标签,不依赖 latest。Docker 的 classic 与 containerd 镜像存储可能返回不同 ID;跨主机以归档校验和与源提交标签核验传输,激活前再与 loaded-image-ids.env 中的目标 ID 比较,拒绝加载后被替换的镜像。归档加载后删除,构建机 ID 保留在 release.env 供追溯。
数据与失败回退
GRAY_DEPLOY_DIR 如 /data/services/gray-logistics-chat,包含:
| 路径 | 内容 |
|---|---|
.project |
服务所有权标记,拒绝复用未知目录 |
data/ |
SQLite、附件和备份,跨发布保留 |
logs/ |
应用日志 |
releases/<commit12>-b<build>/ |
Compose、镜像坐标、私有运行配置和站点候选 |
current-release |
已通过应用及入口检查的发布目录 |
tls/ |
独立 ACME 账号、证书、日志和续期脚本 |
模型密钥写入权限为 600 的 runtime.env,由 Compose 注入进程。验收密码只在 Jenkins 生成 Nginx 哈希,服务器保存哈希文件。
更新前执行 SQLite 在线备份。应用启动或 Nginx 检查失败时,仅恢复本服务之前的 Compose 和站点配置,保留数据;不自动用旧库覆盖新记录。失败发布目录保留供定位,数据库降级及删除数据需另行处理。
新环境自动创建八张业务表,不创建默认客服账号或演示数据。验收用全站密码直接进入工作台;Nginx 验收账号不是应用内客服账号。
HTTPS 及续期
域名须解析到已核实的灰度入口,公网 80、443 端口可达。其他域名的证书不能直接用于新域名。
独立 Certbot 镜像通过 HTTP-01 webroot 签发证书;首次只新增本服务的 HTTP 验证站点,业务接口尚不公开。验证目录为 /var/lib/baiyue-logistics-chat-acme,最终配置持续保留该 HTTP 路径。
证书参数须指向:
<GRAY_DEPLOY_DIR>/tls/config/live/<域名>/fullchain.pem
<GRAY_DEPLOY_DIR>/tls/config/live/<域名>/privkey.pem
ACME 账号和私钥仅保存在服务器私有目录,当前使用无邮箱账号。专用 baiyue-logistics-chat-tls-renew.timer 每日检查本服务证书,内容变化后检查并重载 Nginx,不接管其他证书任务。
排查
先从 Jenkins 构建记录核对阶段及源 SHA。服务器检查:
docker ps --filter name=baiyue-logistics-chat-gray
docker logs --tail 100 baiyue-logistics-chat-gray
systemctl status baiyue-logistics-chat-tls-renew.timer --no-pager
nginx -t
- 构建失败:核对镜像和 PyPI 网络,不跳过测试发布。
- SSH 失败:核对受管凭据和 known_hosts,不禁用指纹检查。
- 证书失败:核对 DNS 和 HTTP 验证路径,保留本服务的验证站点与私有 ACME 状态。
- 容器不健康:检查独立目录的 UID 10001 权限、日志和
/healthz;健康检查不计入业务限流。 - 入口 401:未登录时为预期,使用专用验收密码后应返回 200。
- 流式显示延迟:检查实际 Nginx 或 CDN 是否重新启用了响应缓冲。
独立主机安装另见 Linux 手动参考。凭据与 API 依据 Jenkins 官方文档 和 Remote API,证书验证与续期依据 Certbot 文档。