101 lines
7.1 KiB
Markdown
101 lines
7.1 KiB
Markdown
# 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、日志或示例文件中。
|
|
|
|
## 发布步骤
|
|
|
|
1. 完成检查并提交代码,创建 `gray-chat-YYYYMMDD-<commit12>` 一类不可变发布标签。不要重写已有标签或强推覆盖远端分支;分支有其他更新时先明确发布基线。
|
|
2. 推送标签,在任务 `SOURCE_REF` 选择该标签。Jenkins 按此引用加载流水线并检出代码,镜像记录完整提交 SHA。
|
|
3. 流水线检查 Bash 语法,运行 Node 回归,再构建 `test` 目标执行 Python 回归;通过后构建 `production` 应用镜像及 `certbot` 运维镜像。
|
|
4. 构建完成后才绑定运行凭据。发布脚本校验路径、域名和源提交,生成私有配置并发送镜像及发布文件。服务器验证镜像归档的 SHA-256 后加载,记录目标主机的镜像 ID。
|
|
5. 首次签发域名证书,等待应用健康,再安装本服务的 Nginx 配置。已有业务的容器和站点配置不参与本次发布。
|
|
6. 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 哈希,服务器保存哈希文件。
|
|
|
|
密码哈希位于独立的 `/var/lib/baiyue-logistics-chat-gray-proxy/access.htpasswd`,目录 755、文件 644,供 Nginx 工作进程读取;不放在可能只有 root 可访问的宝塔站点配置目录,也不放明文密码。该目录有本服务所有权标记,不复用未知目录。
|
|
|
|
更新前执行 SQLite 在线备份。应用启动或 Nginx 检查失败时,仅恢复本服务之前的 Compose 和站点配置,保留数据;不自动用旧库覆盖新记录。失败发布目录保留供定位,数据库降级及删除数据需另行处理。
|
|
|
|
新环境自动创建八张业务表,不创建默认客服账号或演示数据。验收用全站密码直接进入工作台;Nginx 验收账号不是应用内客服账号。
|
|
|
|
## HTTPS 及续期
|
|
|
|
域名须解析到已核实的灰度入口,公网 80、443 端口可达。其他域名的证书不能直接用于新域名。
|
|
|
|
独立 Certbot 镜像通过 HTTP-01 webroot 签发证书;首次只新增本服务的 HTTP 验证站点,业务接口尚不公开。验证目录为 `/var/lib/baiyue-logistics-chat-acme`,最终配置持续保留该 HTTP 路径。
|
|
|
|
证书参数须指向:
|
|
|
|
```text
|
|
<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。服务器检查:
|
|
|
|
```bash
|
|
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 手动参考](deployment-linux.md)。凭据与 API 依据 [Jenkins 官方文档](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/) 和 [Remote API](https://www.jenkins.io/doc/book/using/remote-access-api/),证书验证与续期依据 [Certbot 文档](https://eff-certbot.readthedocs.io/en/stable/using.html#webroot)。
|