# 公网部署与完整 XML 流程测试 本目录提供单机 Docker Compose 部署配置:Caddy 负责公网 HTTPS,Web 负责 XML 上传与任务发起,MCP 负责 SuperAgent 处理结果落库。 ## 1. 前置条件 - 一台安装 Docker Engine 与 Docker Compose v2 的 Linux 服务器; - 两个已解析到该服务器的 DNS 名称,例如 `arr.example.com` 和 `mcp.example.com`; - 防火墙仅向公网开放 TCP 80/443(可选开放 UDP 443); - PostgreSQL 15+ 数据库,数据库名必须是 `booking_test`; - 私有、已启用服务端加密且关闭 versioning 的阿里云 OSS bucket; - SuperAgent 已发布的 ARR Agent Open API key; - SuperAgent 能访问 MCP 公网域名,并能通过其受信 `fetch_oss_file` 能力读取同一 OSS bucket。 Web 和 MCP 的 8765/8890 端口只在 Compose 内部网络暴露,不要映射到公网。 ## 2. 数据库状态 若沿用已经验收并记录在 `database/APPLIED_MIGRATIONS.md` 的 `booking_test`,不要重跑任何迁移。 仅对全新、空的 `booking_test`,由有权限的数据库管理员在完成备份/目标核对后依次执行: 1. `database/008_arr_mvp_v1_rebuild.sql` 2. `database/009_source_read_grants.sql` 3. `database/010_mcp_result_ingestion.sql` `008` 会删除并重建该数据库内的 `ingestion`、`booking`、`finance` schema;绝不能对含有未备份业务数据的库执行。`001`–`007` 是历史迁移,不应在 `008` 之后补跑。若数据库尚不存在,`000_create_booking_test_database.sql` 只能由 DBA 在维护库中单独执行。 ## 3. 准备 Secret 配置 ```bash cp deploy/.env.production.example deploy/.env.production chmod 600 deploy/.env.production ``` 编辑 `deploy/.env.production`,替换所有 `replace...` 值。该文件已被 Git 忽略,不能提交。 生成相互独立的随机材料: ```bash openssl rand -hex 32 openssl rand -base64 32 docker run --rm -it caddy:2.10-alpine caddy hash-password ``` - 第一项可作为 `ARR_MCP_BEARER_TOKEN`; - 第二项可作为 `ARR_AGENT_RESULT_HMAC_KEY_B64`; - 第三项会交互式读取 Web 密码并输出 Caddy bcrypt hash。把 hash 写入 env 文件时使用单引号,例如 `WEB_BASIC_AUTH_PASSWORD_HASH='$2a$...'`,避免 `$` 被 Compose 展开; - MCP bearer、SuperAgent Open API key、HMAC key、数据库密码和 OSS 凭据必须彼此独立; - 数据库 URL 中的特殊字符需按 URL 规则编码。 生产环境优先把凭据交给服务器 Secret 管理/RAM/STS。当前 Compose 模板通过进程环境变量注入凭据,适合受控的首次公网测试;不要把 env 文件打进镜像或备份到公开位置。 ## 4. 启动 在仓库根目录执行: ```bash docker compose --env-file deploy/.env.production config --quiet docker compose --env-file deploy/.env.production up -d --build docker compose --env-file deploy/.env.production ps ``` Web 的 Compose 命令明确包含: ```text python -m arr_web.run ... --enable-processing --secure-cookies ``` 镜像的 Dockerfile 默认 Web CMD 也包含 `--enable-processing`。运维若在容器平台 覆盖 CMD/command,必须保留该参数,否则页面会显示“文件接收服务尚未完成生产接线”。 这些部署入口会请求打开 XML 上传处理,但不会绕过健康门禁:Web 只有在数据库、OSS、SuperAgent 和签名配置都装配成功时才返回 `processing_ready=true`。应用源码的 CLI 默认值仍未改成开放;Caddy 会等待 Web/MCP 健康后再接入公网。 查看日志时不要复制或公开 env 文件内容: ```bash docker compose --env-file deploy/.env.production logs --tail=200 web mcp caddy ``` ## 5. 公网验收 先验证 Web。下面命令会让 `curl` 交互式询问 Basic Auth 密码,避免把密码写进 shell history: ```bash export WEB_PUBLIC_HOST=arr.example.com export WEB_BASIC_AUTH_USER=arrtester curl --fail --user "$WEB_BASIC_AUTH_USER" "https://$WEB_PUBLIC_HOST/api/health" ``` 响应中的以下值必须同时为 `true`: ```json { "database_ready": true, "processing_ready": true } ``` 若 `processing_ready=false`,不要开始 XML 测试;优先核对数据库目标、OSS bucket 策略/加密/versioning、OSS 环境凭据、SuperAgent URL/key 和 HMAC 配置。 再验证 MCP 的认证边界: ```bash export MCP_PUBLIC_HOST=mcp.example.com curl --silent --output /dev/null --write-out '%{http_code}\n' "https://$MCP_PUBLIC_HOST/mcp" ``` 未认证请求必须返回 `401`。随后从 Secret 管理器读取 bearer,在不回显的终端变量中执行 MCP `initialize`/`tools/list`;认证后的发现结果应且只能包含 `arr_submit_processing_result`。完成后立即 `unset ARR_MCP_TOKEN`。 ## 6. 重新绑定 SuperAgent MCP 在 SuperAgent MCP 管理中使用: - 地址:`https:///mcp` - Header:`Authorization: Bearer `(使用平台 Secret 引用) - OAuth:空 - 工具:只启用 `arr_submit_processing_result` 公网域名与临时 ngrok 地址不同,因此必须重新执行“连接/发现工具/保存”,再把 MCP 绑定到 ARR Agent 的新草稿并发布。只有工具发现成功且 Agent 已保存到当前发布版本后,才能进行页面上传测试。 ## 7. 完整 XML 测试 1. 登录 `https:///`; 2. 上传一份不含真实住客隐私的 Opera XML; 3. 确认页面返回 `job_id`,任务状态进入 queued/running; 4. 在 SuperAgent 确认本次会话只读取该 OSS XML,并调用唯一 ARR MCP 工具; 5. 以 MCP receipt 的 `committed` 或 `already_committed` 为落库成功依据;Agent 页面单独显示 `success` 不等于数据库已提交; 6. 回到 Web 核对日报历史、数据库月度投影和渠道看板。 ## 8. 更新与回退 ```bash git pull --ff-only docker compose --env-file deploy/.env.production up -d --build ``` 不要强制覆盖仓库历史,也不要把数据库迁移放进容器自动启动。回退应用镜像前先核对数据库 schema 兼容性;数据库回滚脚本只能按各文件顶部门禁人工执行。 ## 当前未完成项 - 日报入库后自动触发月报仍未实现; - 月报 `TOTAL PRICE` 的指定公式规则仍未实现; - 本 Compose 配置因此只开启 XML processing,不开启月报、公司报表或旧 callback 写入开关。 完成一笔无隐私 XML 的公网竖切前,部署只能标记为“服务已启动”,不能标记为“业务链路已验收”。