docs: 建立 Admin 部署与运维 Wiki (#316)
This commit is contained in:
@@ -48,10 +48,12 @@ CORE_PAGE_PATHS = {
|
||||
"Product-Requirements-Overview": (
|
||||
"docs/09-product-requirements-overview.md"
|
||||
),
|
||||
"Deployment-and-Operations": "docs/10-deployment-and-operations.md",
|
||||
"Delivery-Documentation-Guide": "docs/delivery/README.md",
|
||||
"Audience-Document-Template": (
|
||||
"docs/delivery/audience-document-template.md"
|
||||
),
|
||||
"Deployment-Template": "docs/templates/deployment.md",
|
||||
"Task-Archive-Template": "docs/templates/task-archive.md",
|
||||
}
|
||||
CORE_DOCUMENT_REQUIREMENTS = {
|
||||
@@ -130,6 +132,19 @@ CORE_DOCUMENT_REQUIREMENTS = {
|
||||
"## 更新时机",
|
||||
"## 最小验收清单",
|
||||
),
|
||||
"docs/10-deployment-and-operations.md": (
|
||||
"## 本页用途",
|
||||
"## 安全边界",
|
||||
"## 服务概览",
|
||||
"## 环境要求",
|
||||
"## 配置与凭据来源",
|
||||
"## 首次部署",
|
||||
"## 日常发布",
|
||||
"## 健康检查与日志",
|
||||
"## 数据库迁移、备份与恢复",
|
||||
"## 回退",
|
||||
"## 已知限制",
|
||||
),
|
||||
"docs/delivery/README.md": (
|
||||
"## 什么时候需要交付文档",
|
||||
"## 受众与文档选择",
|
||||
@@ -156,6 +171,8 @@ REQUIRED_FILES = (
|
||||
"README.md",
|
||||
"docs/00-project-profile.md",
|
||||
"docs/01-workflow.md",
|
||||
"docs/10-deployment-and-operations.md",
|
||||
"docs/templates/deployment.md",
|
||||
"docs/templates/task-archive.md",
|
||||
*CORE_DOCUMENT_REQUIREMENTS,
|
||||
"wiki-docs.json",
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
<!-- gitea-wiki-mirror:start -->
|
||||
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
|
||||
wiki_page: Deployment-and-Operations
|
||||
wiki_url: https://git.ilapage.cn/OPC/cmautobuy/wiki/Deployment-and-Operations.-
|
||||
wiki_revision: c15ad8664ed54ffd90a1b9b6d5b8bc77e2256153
|
||||
synchronized_at: 2026-08-26T09:09:00Z
|
||||
<!-- gitea-wiki-mirror:end -->
|
||||
|
||||
# Admin 部署与运维
|
||||
|
||||
## 本页用途
|
||||
|
||||
本页供 cmautobuy 内部维护者部署和运维生产 Admin。日常发布以仓库 `admin/deploy/deploy-admin.ps1` 为唯一入口;本页解释它的安全门禁、预期结果和人工停止位置,不另造一套会漂移的手工发布流程。
|
||||
|
||||
## 安全边界
|
||||
|
||||
- 部署会连接生产服务器、备份 MySQL、安装 release、重启 systemd 并改变公网服务;只有用户明确要求部署时才能执行。
|
||||
- 本页只记录配置名称和安全来源,不记录真实密码、Token、Cookie、私钥或证书内容。
|
||||
- 默认禁止 schema 升级;只有确认迁移和回退兼容性后显式使用 `-AllowSchemaMigration`。
|
||||
- 脚本可以在切换失败时恢复上一稳定二进制,但数据库迁移不会自动反向恢复。
|
||||
- 恢复数据库备份会覆盖备份后的业务数据,必须停止服务、确认影响并由负责人单独授权。
|
||||
- 发布脚本不会触发顺运宝同步、目录导入、AI 调用、采集、采购、下单或付款。
|
||||
|
||||
## 服务概览
|
||||
|
||||
| 项目 | 当前值 |
|
||||
|---|---|
|
||||
| systemd 服务 | `cmautobuy-admin` |
|
||||
| 运行账号 | `cmautobuy:cmautobuy` |
|
||||
| 工作目录 | `/opt/cmautobuy` |
|
||||
| 稳定二进制 | `/opt/cmautobuy/cmautobuy-admin`,指向 release |
|
||||
| release 目录 | `/opt/cmautobuy/releases/<提交短号>/` |
|
||||
| 稳定配置 | `/opt/cmautobuy/config.yaml` |
|
||||
| 稳定数据目录 | `/opt/cmautobuy/data/` |
|
||||
| 环境文件 | `/etc/cmautobuy/admin.env`,权限受控 |
|
||||
| AI 密钥目录 | `/etc/cmautobuy/secrets/` |
|
||||
| 内部监听 | `127.0.0.1:18080` |
|
||||
| 预检监听 | `127.0.0.1:18083`,临时 |
|
||||
| 公网入口 | `https://buy.833729.com`,由 nginx 反向代理 |
|
||||
| 数据库 | MySQL 8.4,数据库 `autobuy` |
|
||||
| 备份目录 | `/opt/cmautobuy/backups/` |
|
||||
|
||||
systemd 单元模板在 `admin/deploy/cmautobuy-admin.service`。服务只监听本机地址,不把 18080/18083 直接暴露到公网。
|
||||
|
||||
## 环境要求
|
||||
|
||||
### Windows 构建机
|
||||
|
||||
从仓库根目录检查:
|
||||
|
||||
```powershell
|
||||
git --version
|
||||
go version
|
||||
tar --version
|
||||
ssh -V
|
||||
scp
|
||||
```
|
||||
|
||||
预期这些命令均存在。部署脚本会强制使用 Go 1.23.0,运行 Admin 全量 test、build、vet,再交叉构建 `linux/amd64`、`CGO_ENABLED=0` 单文件。
|
||||
|
||||
### Linux 服务器
|
||||
|
||||
远端执行器要求 `bash`、`sha256sum`、`mysql`、`mysqldump`、`gzip`、`curl`、`systemctl`、`ss`、`runuser`、`install`、`readlink` 和 `nginx`。缺少任一命令都会在修改生产前停止。
|
||||
|
||||
只读检查:
|
||||
|
||||
```bash
|
||||
systemctl is-enabled cmautobuy-admin
|
||||
systemctl is-active cmautobuy-admin
|
||||
nginx -t
|
||||
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:18080/
|
||||
```
|
||||
|
||||
预期:systemd 已启用且 active;nginx 配置测试成功;Admin 根路径返回 `303`。
|
||||
|
||||
## 配置与凭据来源
|
||||
|
||||
| 名称 | 用途 | 安全来源 | 敏感 |
|
||||
|---|---|---|---|
|
||||
| `CMAUTOBUY_DB_HOST` / `PORT` / `NAME` / `USER` | MySQL 连接定位 | `/etc/cmautobuy/admin.env` | 部分 |
|
||||
| `CMAUTOBUY_DB_PASSWORD` | MySQL 业务账号密码 | 同一权限受控环境文件 | 是 |
|
||||
| `CMAUTOBUY_DB_TLS_MODE` / `TLS_CA` | MySQL TLS 验证 | 环境文件和服务器 CA 路径 | CA 路径否,内容不写入本页 |
|
||||
| `CMAUTOBUY_CATALOG_SOURCE` | 商品目录来源名 | 环境文件 | 否 |
|
||||
| `CMAUTOBUY_CATALOG_TOKEN` | 商品目录接口认证 | 环境文件 | 是 |
|
||||
| `CMAUTOBUY_AI_SECRETS_PATH` | AI 密钥文件目录 | `/etc/cmautobuy/secrets/` | 路径否,内容是 |
|
||||
| `CMAUTOBUY_AI_ALLOWED_HOSTS` | AI 服务允许主机 | 环境文件 | 否 |
|
||||
| MySQL 管理 defaults 文件 | 部署备份和 schema 只读检查 | 服务器 root 专用受控文件 | 是 |
|
||||
| SSH 私钥 | 生产 SSH 认证 | 维护者本机受控路径或 ssh-agent | 是 |
|
||||
|
||||
脚本使用 `BatchMode=yes` 和严格主机密钥检查,不接收或保存 SSH 密码。
|
||||
|
||||
## 首次部署
|
||||
|
||||
首次准备 systemd、nginx、运行账号、目录、环境文件、TLS CA 和数据库权限属于独立运维变更,不能用日常发布脚本替代。最少要完成:
|
||||
|
||||
1. 创建 `cmautobuy` 系统账号及 `/opt/cmautobuy`、`/etc/cmautobuy` 必要目录。
|
||||
2. 将受控配置和环境文件按最小权限放置,真实值不进入 Git。
|
||||
3. 安装并启用 `cmautobuy-admin.service`,确认内部只监听 `127.0.0.1:18080`。
|
||||
4. 配置 nginx 和 HTTPS,`nginx -t` 通过后才 reload。
|
||||
5. 建立 MySQL 8.4 数据库、业务账号、TLS 与备份管理配置。
|
||||
6. 先用独立测试库验证当前 schema,再对生产执行有明确授权的首次迁移。
|
||||
7. 运行本文“健康检查”。
|
||||
|
||||
首次部署涉及生产权限和数据,必须有独立工单、回退方案和实际运维确认。
|
||||
|
||||
## 日常发布
|
||||
|
||||
### 1. 只读预览
|
||||
|
||||
从仓库根目录:
|
||||
|
||||
```powershell
|
||||
.\admin\deploy\deploy-admin.ps1 -WhatIf
|
||||
```
|
||||
|
||||
预期只显示固定提交、目标服务器和是否允许迁移;不构建、不上传、不备份、不重启。
|
||||
|
||||
### 2. 发布无 schema 变化的版本
|
||||
|
||||
```powershell
|
||||
.\admin\deploy\deploy-admin.ps1 -Commit <已提交的完整哈希或可解析引用>
|
||||
```
|
||||
|
||||
脚本只使用 `git archive <固定提交>` 的内容。工作区可以有无关未提交修改,但不会进入发布物;需要发布的新代码必须先提交并推送。
|
||||
|
||||
### 3. 发布含 schema 迁移的版本
|
||||
|
||||
当前 2026-08-26 代码声明 MySQL schema v31。生产低于目标版本时,普通发布会在修改前停止并提示目标版本。确认 v31 迁移、自检、旧二进制兼容性和备份恢复代价后,显式执行:
|
||||
|
||||
```powershell
|
||||
.\admin\deploy\deploy-admin.ps1 -Commit <目标提交> -AllowSchemaMigration
|
||||
```
|
||||
|
||||
`-AllowSchemaMigration` 只允许新 release 在备份完成后、18083 独立端口预检时执行仓库中已有迁移;它不跳过 schema 自检,也不授权恢复备份。
|
||||
|
||||
### 固定安全步骤
|
||||
|
||||
1. 解析并记录 40 位 Git 提交和目标 schema。
|
||||
2. 在隔离源码上用 Go 1.23.0 执行 test、build、vet。
|
||||
3. 构建 Linux amd64 二进制并计算 SHA-256。
|
||||
4. 上传到随机 `/tmp` 路径,服务器核对 SHA。
|
||||
5. 检查当前 systemd、schema 和四类后台活动任务。
|
||||
6. 创建 MySQL 单事务 gzip 备份并检查 gzip、建表语句和 SHA-256。
|
||||
7. 安装到新 release,只链接稳定配置和数据。
|
||||
8. 在 `127.0.0.1:18083` 启动预检,核对根路径、登录页、目标 schema 和后台空闲。
|
||||
9. 原子切换稳定二进制并重启 systemd。
|
||||
10. 核对稳定链接、systemd、nginx、本机 18080、公网根路径和登录页。
|
||||
|
||||
任一步失败都不能宣称部署成功。
|
||||
|
||||
## 健康检查与日志
|
||||
|
||||
每次发布或回退后:
|
||||
|
||||
```bash
|
||||
systemctl is-active cmautobuy-admin
|
||||
readlink -f /opt/cmautobuy/cmautobuy-admin
|
||||
nginx -t
|
||||
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:18080/
|
||||
curl -sS -o /dev/null -w '%{http_code}\n' https://buy.833729.com/
|
||||
curl -sS -o /dev/null -w '%{http_code}\n' https://buy.833729.com/login
|
||||
journalctl -u cmautobuy-admin -n 100 --no-pager
|
||||
```
|
||||
|
||||
预期:服务 active;稳定链接指向目标 release;nginx 测试通过;根路径返回 `303`;登录页返回 `200`;日志没有新的致命错误。
|
||||
|
||||
schema 和后台任务核对使用服务器本机受控 MySQL 管理配置执行,不把命令输出中的业务数据复制到工单或文档。
|
||||
|
||||
## 数据库迁移、备份与恢复
|
||||
|
||||
部署前备份写入 `/opt/cmautobuy/backups/autobuy-before-<release>-<UTC时间>-notablespaces.sql.gz`,权限 `0600`。脚本验证:
|
||||
|
||||
- gzip 可完整解压;
|
||||
- 备份至少包含一条 `CREATE TABLE`;
|
||||
- 记录 SHA-256;
|
||||
- 使用 `--single-transaction --routines --triggers --no-tablespaces`。
|
||||
|
||||
脚本不会删除历史 release 和备份。
|
||||
|
||||
恢复备份不是日常自动回退步骤。需要恢复时必须先停止 Admin,确认将丢失的备份后数据,保存当前故障库证据,在独立环境演练恢复和 schema 自检,再由负责人授权生产恢复。恢复后重新执行登录、schema、任务关系和关键业务数量核对。
|
||||
|
||||
## 回退
|
||||
|
||||
- 切换后 systemd、本机 18080、nginx 或公网健康检查失败时,远端执行器会把稳定链接恢复到上一可执行 release 并重启服务。
|
||||
- 自动回退只处理二进制链接,不恢复数据库。
|
||||
- 如果新版本已经把 schema 从 v30 升到 v31,只有确认上一二进制兼容 v31 时才能继续使用自动代码回退;不兼容时停止发布并走人工数据库恢复决策。
|
||||
- 手工回退前先记录当前 release、上一 release、当前 schema、备份路径与 SHA,不删除故障 release。
|
||||
- 回退后必须重新执行健康检查,未全部通过时立即人工处理。
|
||||
|
||||
## 已知限制
|
||||
|
||||
- 当前为单机 systemd 部署,没有灰度、多实例滚动发布。
|
||||
- #309 的脚本已完成本地语法、测试、隔离构建和失败上传路径验证;截至其验收记录,尚未在该脚本下实际演练生产备份、18083 预检、v31 迁移、原子切换和自动回退。
|
||||
- 数据库备份恢复不会自动执行,也尚未作为日常脚本能力提供。
|
||||
- 本页不代替生产变更工单和用户明确部署授权。
|
||||
+3
-2
@@ -2,8 +2,8 @@
|
||||
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
|
||||
wiki_page: Home
|
||||
wiki_url: https://git.ilapage.cn/OPC/cmautobuy/wiki/Home
|
||||
wiki_revision: 900fea2efd1e4d3631536c1c7028d9e7f257e520
|
||||
synchronized_at: 2026-08-26T08:53:19Z
|
||||
wiki_revision: d3e7d43c3ba0868ba4d7deb801f6bce87c41caa9
|
||||
synchronized_at: 2026-08-26T09:11:13Z
|
||||
<!-- gitea-wiki-mirror:end -->
|
||||
|
||||
# cmautobuy 文档首页
|
||||
@@ -53,6 +53,7 @@ C:/Python310/python.exe -m unittest discover -s test -v
|
||||
| 分析报错 | [故障排查](Troubleshooting) |
|
||||
| 建工单、实施、验收 | [开发工作流](Development-Workflow) |
|
||||
| 写面向采购员或运维的文档 | [交付文档指南](Delivery-Documentation-Guide) |
|
||||
| 部署或回退 Admin | [Admin 部署与运维](Deployment-and-Operations) |
|
||||
|
||||
## 详细文档
|
||||
|
||||
|
||||
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
<!-- gitea-wiki-mirror:start -->
|
||||
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
|
||||
wiki_page: Deployment-Template
|
||||
wiki_url: https://git.ilapage.cn/OPC/cmautobuy/wiki/Deployment-Template.-
|
||||
wiki_revision: 78a3f02ad22e9fb94c3437670cb30fef39cac5b8
|
||||
synchronized_at: 2026-08-26T09:09:09Z
|
||||
<!-- gitea-wiki-mirror:end -->
|
||||
|
||||
# 部署文档模板
|
||||
|
||||
> 本页是技术栈中立的内部维护模板,不描述任何真实服务。常驻服务项目复制本结构建立自己的 `Deployment-and-Operations` 页面;没有常驻服务时不要创建空页面。
|
||||
|
||||
## 本页用途
|
||||
|
||||
说明读者、环境和完成部署后应达到的可验证结果。
|
||||
|
||||
## 安全边界
|
||||
|
||||
- 只记录配置项名称和安全来源,不写真实密码、Token、私钥、证书内容或个人数据。
|
||||
- 发布、迁移、恢复备份和删除必须写明授权条件、影响和停止位置。
|
||||
- 每条命令注明执行位置、是否改变外部状态和预期结果。
|
||||
|
||||
## 服务概览
|
||||
|
||||
| 项目 | 内容 |
|
||||
|---|---|
|
||||
| 服务名 | 填写 |
|
||||
| 运行账号 | 填写 |
|
||||
| 代码/发布目录 | 填写 |
|
||||
| 进程管理 | systemd / supervisor / 容器 / 其他 |
|
||||
| 内部监听 | 填写 |
|
||||
| 外部入口 | 填写 |
|
||||
| 数据与依赖 | 填写 |
|
||||
| 日志入口 | 填写 |
|
||||
|
||||
## 环境要求
|
||||
|
||||
列出操作系统、运行时、数据库、反向代理、构建机和命令版本,以及可复制的检查命令和预期结果。
|
||||
|
||||
## 配置与凭据来源
|
||||
|
||||
用表格写配置名称、用途、非敏感来源路径和是否敏感。敏感值只说明从哪个受控位置取得。
|
||||
|
||||
## 首次部署
|
||||
|
||||
按“创建账号与目录 → 安装服务和接入层 → 放置受控配置 → 备份 → 迁移 → 启动 → 健康检查”的真实顺序编写。
|
||||
|
||||
## 日常发布
|
||||
|
||||
记录固定提交、构建、上传、备份、预检、切换、验证和证据;发布脚本存在时以脚本为唯一日常入口,不复制一套手工命令造成分叉。
|
||||
|
||||
## 健康检查与日志
|
||||
|
||||
列出进程、内部 HTTP、外部 HTTPS、数据库版本和后台任务检查,以及服务日志、接入层日志和发布日志入口。
|
||||
|
||||
## 数据库迁移、备份与恢复
|
||||
|
||||
说明迁移授权、备份格式、完整性检查、保留位置、恢复前停止条件和恢复后的核对。代码回退与数据库恢复必须分开描述。
|
||||
|
||||
## 回退
|
||||
|
||||
说明自动回退范围、人工回退前置条件和无法安全回退时的停止位置。
|
||||
|
||||
## 已知限制
|
||||
|
||||
必须填写实际未演练或不支持的范围;没有就写“无”,不得保留占位文字。
|
||||
@@ -95,6 +95,23 @@ class CoreDocumentTests(unittest.TestCase):
|
||||
required = CORE_DOCUMENT_REQUIREMENTS["docs/00-project-profile.md"]
|
||||
self.assertIn("## DevHarness 来源与基线", required)
|
||||
|
||||
def test_admin_deployment_pages_are_required_and_mapped(self) -> None:
|
||||
config = load_config()
|
||||
mappings = {mapping.page: mapping.path for mapping in config.mappings}
|
||||
self.assertEqual(
|
||||
mappings.get("Deployment-and-Operations"),
|
||||
"docs/10-deployment-and-operations.md",
|
||||
)
|
||||
self.assertEqual(
|
||||
mappings.get("Deployment-Template"),
|
||||
"docs/templates/deployment.md",
|
||||
)
|
||||
required = CORE_DOCUMENT_REQUIREMENTS[
|
||||
"docs/10-deployment-and-operations.md"
|
||||
]
|
||||
self.assertIn("## 数据库迁移、备份与恢复", required)
|
||||
self.assertIn("## 回退", required)
|
||||
|
||||
def test_missing_or_wrong_core_mapping_is_reported(self) -> None:
|
||||
errors = core_mapping_errors({"Home": "docs/wrong.md"})
|
||||
self.assertTrue(any("Home -> docs/README.md" in error for error in errors))
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
{"page": "Common-Changes", "path": "docs/05-common-changes.md"},
|
||||
{"page": "Troubleshooting", "path": "docs/06-troubleshooting.md"},
|
||||
{"page": "Product-Requirements-Overview", "path": "docs/09-product-requirements-overview.md"},
|
||||
{"page": "Deployment-and-Operations", "path": "docs/10-deployment-and-operations.md"},
|
||||
{"page": "Delivery-Documentation-Guide", "path": "docs/delivery/README.md"},
|
||||
{"page": "Audience-Document-Template", "path": "docs/delivery/audience-document-template.md"},
|
||||
{"page": "Deployment-Template", "path": "docs/templates/deployment.md"},
|
||||
{"page": "Task-Archive-Template", "path": "docs/templates/task-archive.md"},
|
||||
|
||||
{"page": "Client-Getting-Started", "path": "docs/client/00-getting-started.md"},
|
||||
|
||||
Reference in New Issue
Block a user