diff --git a/CONTEXT.md b/CONTEXT.md index b43b228..f41405c 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -21,7 +21,7 @@ | `internal/integration/superagent` | SuperAgent Open API 出站适配 | 已实现并通过模拟 Provider 测试,默认关闭 | | `cmd/superagent-probe` | 无业务数据的显式连通性探针 | 已实现;需要项目专属测试配置 | | `cmd/postgis-probe` | 不读取业务行的 PostGIS readiness 探针 | 已实现;需要只读数据库配置 | -| `Dockerfile` / `compose.yaml` | 测试环境容器构建与单实例进程托管 | 已建立;只发布宿主机回环端口,目标服务器尚未验证 | +| `Dockerfile` / `compose.yaml` | 测试环境容器构建与单实例进程托管 | 已建立;容器内监听 8080,只发布宿主机回环端口 16587,目标服务器尚未验证 | | `pkg` | 可被外部 module 复用的稳定 Go API | 当前为空 | | `docs/import` | 字段/表映射、通用模板和本地数据库样例 | 样例 SQL 含受限数据并被 Git 忽略,不会执行 | | SuperAgent | 对话理解、工具选择和答案组织 | 已按仓库内 2026-07-12 协议基线实现客户端;当前环境待联调 | @@ -41,7 +41,7 @@ - MCP:标准库 HTTP/JSON-RPC,协议基线 `2025-06-18`,同步 JSON 响应,独立 Bearer 和 7 个只读工具;地名工具只搜索现有业务记录并要求用户确认候选。 - PostgreSQL:`github.com/jackc/pgx/v5 v5.10.0` 原生连接池;连接默认只读并设置 statement timeout。 - PostGIS:`ST_Covers`、`ST_DWithin`、`ST_Distance` 和 `ST_ClosestPoint`;只在实库确认 EPSG:4326 后启用。 -- 部署:多阶段 Docker 镜像与单实例 Compose;Secret 通过未提交的 `.env` 在运行时注入,应用端口只发布到宿主机 `127.0.0.1:8080`,由宿主机 Nginx 终止 TLS。 +- 部署:多阶段 Docker 镜像与单实例 Compose;Secret 通过未提交的 `.env` 在运行时注入,容器内 8080 只发布到宿主机 `127.0.0.1:16587`,由宿主机 Nginx 终止 TLS。 ### 计划但尚未接入或确认 diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 4fd79be..8176270 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -5,7 +5,7 @@ | 最近更新 | 2026-09-05 | | 当前分支 | `main` | | 当前阶段 | 对话、SuperAgent、空间 MCP 与测试环境容器部署基线已完成 | -| 当前重点 | 将代码提交并推送后,在目标服务器验证 Compose、Nginx、真实消防 Profile 与公网 MCP 链路 | +| 当前重点 | 在目标服务器验证宿主机 16587 端口映射、Nginx、真实消防 Profile 与公网 MCP 链路 | ## 1. 当前 Checkpoint @@ -17,7 +17,7 @@ 当前进展: - `Dockerfile` 使用显式 Go/Alpine 版本的多阶段构建,在构建阶段执行全部 Go 测试,最终镜像只包含静态服务二进制、CA 和时区数据,并以非 root 用户运行。 -- `compose.yaml` 只运行一个 API 实例,从未提交的 `.env` 注入配置,强制清空一次性迁移 DSN,只把 8080 发布到宿主机 `127.0.0.1`,并设置健康检查、只读文件系统、权限收紧和日志轮转。 +- `compose.yaml` 只运行一个 API 实例,从未提交的 `.env` 注入配置,强制清空一次性迁移 DSN,把容器内 8080 发布到宿主机 `127.0.0.1:16587`,并设置健康检查、只读文件系统、权限收紧和日志轮转。 - 现有 PostgreSQL/PostGIS 不进入 Compose;同宿主机数据库需要使用容器可达的宿主机地址,且仍需受 `listen_addresses`、`pg_hba.conf` 和防火墙约束。 - Nginx 示例增加 HTTP 到 HTTPS 跳转和 HTTP 429 JSON 限流响应,仍不比较、保存或注入 Chat、MCP、SuperAgent 或数据库 Secret。 - 运维手册记录 Git 前置条件、服务器目录、Secret 权限、Compose/Nginx 启停、Chat/MCP 冒烟、SuperAgent 回调、更新和回滚。 @@ -32,8 +32,8 @@ ## 2. 当前优先级 -1. 由用户审查当前变更后创建首个 Git 提交并推送 `origin/main`;当前无提交,服务器尚不能 clone。 -2. 在 `/home/firee-safety-ymd` 构建并启动 Compose,确认健康状态、数据库可达和 8080 只绑定回环地址。 +1. 由用户审查本 checkpoint 变更后提交并推送 `origin/main`;服务器只部署明确提交的 revision。 +2. 在 `/home/firee-safety-ymd` 构建并启动 Compose,确认宿主机 16587 只绑定回环地址、容器内 8080 健康可达且数据库连接正常。 3. 在目标机迁移 Nginx 配置并执行 `nginx -t` 后 reload;只公开 HTTPS 兼容路径、`/mcp` 和可选 `/health`。 4. 使用项目专属测试 Key 和已发布消防 Profile 做兼容 `completion` 首轮/多轮真实冒烟,核对最终回答、用量和会话复用。 5. 为所有查询表补齐适用 GiST 索引并验证查询计划;当前小数据可做联调,但生产前必须完成索引与并发验证。 @@ -41,7 +41,7 @@ ## 3. 已确认事实 -- 仓库已初始化 Git,当前分支是 `main`,已有远程 `origin`;尚无提交。 +- 仓库已初始化 Git,当前分支是 `main`,已有远程 `origin`;基线提交 `8a6c31c` 已推送到 `origin/main`。 - `docs/import/字段组.xlsx` 和 `docs/import/数据表映射.xlsx` 是用户已有、已暂存的变更,本 checkpoint 未修改。 - 用户已使用项目只读 probe 成功连接数据库 `fire_safety_ymd`;PostGIS 报告版本 `3.3 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`,8 表合计 4,055 条记录。 - 实库 4,048 条非空几何已在 2026-09-05 的受控事务中从 SRID 0 补齐为 SRID 4326;坐标 extent 约为经度 121.16 至 121.93、纬度 37.07 至 37.49,类型与预期一致且未发现 WGS84 数值越界。数据提供方确认 8 表源数据均为 EPSG:4326 且无坐标偏移,严格 readiness 已通过。 @@ -56,8 +56,8 @@ - 用户对话 API、SuperAgent Open API Adapter 和 MCP endpoint 都默认关闭;Chat Bearer、Open API Key 和 MCP Token 属于三个独立信任方向并禁止复用。 - `/api/chat` 已实现单进程内存会话映射、同会话并发 Run 冲突和严格 SSE 最终回答;模拟 Provider 端到端测试通过,真实 SuperAgent 尚未通过该入口联调。 - 可选兼容入口已实现截图所示路径、`xtoken`、`input.prompt/session_id` 和 `event: result` 外形;正文仍只在严格成功的 `stop` 事件中出现,不是 DashScope 全量 API。 -- `Dockerfile`、`.dockerignore` 和 `compose.yaml` 已建立测试部署基线;容器单实例运行,8080 仅发布到宿主机回环地址,一次性迁移 DSN 在服务容器中强制为空。 -- `deploy/nginx/fire-safety-ymd.conf.example` 已将公网调用指向 `127.0.0.1:8080`,不再保存或注入任何 Provider/Chat/MCP Secret;目标机 Nginx 尚未验证。 +- `Dockerfile`、`.dockerignore` 和 `compose.yaml` 已建立测试部署基线;容器单实例运行,容器内 8080 仅发布到宿主机 `127.0.0.1:16587`,一次性迁移 DSN 在服务容器中强制为空。 +- `deploy/nginx/fire-safety-ymd.conf.example` 已将公网调用指向宿主机 `127.0.0.1:16587`,再由 Docker 映射到容器 8080;配置不保存或注入任何 Provider/Chat/MCP Secret,目标机 Nginx 尚未验证。 - 用户确认真实数据包含大量镇街,环境变量不适合枚举全量值;MCP 现支持显式数据库全范围 `all` 和默认镇街白名单 `town_allowlist` 两种服务端范围。 - 用户选择先实现简单地名能力、后续再优化;当前只查询既有森林防火记录,不调用外部地图服务,也不把候选代表点自动认定为演练点。 - 本地真实 MCP 冒烟已完成:7 个工具均成功访问实库,响应和错误边界符合契约;该结果不等于公网、SuperAgent 或生产并发已验证。 @@ -87,8 +87,8 @@ 完成条件: -- 用户完成首个 Git 提交并推送后,目标机能在 `/home/firee-safety-ymd` clone 或 `git pull --ff-only` 到明确 revision。 -- `docker compose build --pull`、`up -d` 和容器健康检查通过,8080 只绑定 `127.0.0.1`,运行容器中没有迁移凭证。 +- 用户提交并推送本 checkpoint 后,目标机能在 `/home/firee-safety-ymd` clone 或 `git pull --ff-only` 到明确 revision。 +- `docker compose build --pull`、`up -d` 和容器健康检查通过,宿主机 16587 只绑定 `127.0.0.1`,运行容器中没有迁移凭证。 - 在目标机替换安全 App ID、执行 `nginx -t` 后 reload,并验证 TLS、HTTP 到 HTTPS 跳转、429 和未列出路径 404。 - 使用无敏感信息的问题验证兼容首轮 `null -> stop`、后续 `session_id` 复用、错误 xtoken、断流和超时。 - 配置 SuperAgent 对公网 `/mcp` 的独立 Bearer,验证真实工具调用、TLS 和 warning 保留。 diff --git a/compose.yaml b/compose.yaml index 13a14c1..15ee076 100644 --- a/compose.yaml +++ b/compose.yaml @@ -17,7 +17,7 @@ services: FIRE_SAFETY_POSTGIS_MIGRATION_DSN: "" TZ: Asia/Shanghai ports: - - "127.0.0.1:8080:8080" + - "127.0.0.1:16587:8080" extra_hosts: # Use host.docker.internal in the DSN only when PostgreSQL runs on this # same host; a remote/private database hostname is preferred otherwise. diff --git a/deploy/nginx/fire-safety-ymd.conf.example b/deploy/nginx/fire-safety-ymd.conf.example index f0760f7..bdf53f4 100644 --- a/deploy/nginx/fire-safety-ymd.conf.example +++ b/deploy/nginx/fire-safety-ymd.conf.example @@ -10,7 +10,7 @@ limit_req_zone $binary_remote_addr zone=fire_safety_chat:10m rate=5r/s; limit_req_zone $binary_remote_addr zone=fire_safety_mcp:10m rate=20r/s; upstream fire_safety_ymd_backend { - server 127.0.0.1:8080; + server 127.0.0.1:16587; keepalive 16; } diff --git a/docs/architecture/public-chat-entry-v1.md b/docs/architecture/public-chat-entry-v1.md index 232efb1..3f4d028 100644 --- a/docs/architecture/public-chat-entry-v1.md +++ b/docs/architecture/public-chat-entry-v1.md @@ -5,7 +5,7 @@ ```mermaid flowchart LR C[既有用户客户端] -->|HTTPS + xtoken\nDashScope 风格 JSON/SSE| N[Nginx] - N -->|HTTP 127.0.0.1:8080| D[兼容 Chat Handler] + N -->|HTTP 127.0.0.1:16587
宿主机映射到容器 :8080| D[兼容 Chat Handler] D -->|ChatRequest / ChatTurn| S[共享 Chat Service] S -->|Provider-neutral port| A[SuperAgent Adapter] A -->|Open API Key + HTTPS/SSE| SA[SuperAgent] @@ -43,7 +43,7 @@ Nginx 不再直接调用 DashScope。它只负责 TLS、精确公开路径、基 ## 5. 网络与伸缩边界 -- Go 推荐只监听 `127.0.0.1:8080`,公网只开放 Nginx 443;PostgreSQL 5432 不对公网开放。 +- Docker 部署中 Go 在容器内监听 `:8080`,宿主机只发布 `127.0.0.1:16587` 给 Nginx;若直接运行二进制,则监听 `127.0.0.1:16587`。公网只开放 Nginx 443,PostgreSQL 5432 不对公网开放。 - Nginx 对兼容路径关闭缓冲、缓存、gzip 和重试,超时必须覆盖 Go Chat Run Timeout。 - `/mcp` 使用独立 Bearer;Chat `xtoken`、MCP Bearer 与 SuperAgent Open API Key 三者不得复用。 - 当前会话在单进程内存中。多实例部署必须先实现共享会话映射或粘性路由;否则后续轮次可能落到另一实例并返回 404。 diff --git a/docs/project/operations/docker-test-deployment.md b/docs/project/operations/docker-test-deployment.md index aa47723..c7718a9 100644 --- a/docs/project/operations/docker-test-deployment.md +++ b/docs/project/operations/docker-test-deployment.md @@ -4,7 +4,7 @@ | --- | --- | | 目标服务器目录 | /home/firee-safety-ymd | | 运行方式 | 宿主机 Nginx 终止 HTTPS,Docker Compose 运行单个 Go 服务 | -| 应用监听边界 | 只把容器端口发布到宿主机 127.0.0.1:8080 | +| 应用监听边界 | 容器内监听 8080,只发布到宿主机 127.0.0.1:16587 | | 数据库 | 使用现有 PostgreSQL/PostGIS;本手册不创建数据库容器、不导入 SQL | | 状态 | 测试环境部署基线;目标服务器、公网 DNS/TLS 和 SuperAgent 回调仍需现场验证 | @@ -12,16 +12,16 @@ ## 1. 部署前提 -本仓库在本手册编写时尚无 Git 提交。服务器不能直接 clone 当前工作区,必须由项目维护者先审阅变更、手动 commit 并 push 到远程仓库;本项目不会自动提交、推送或迁移服务器数据。以下命令以发布 `main` 分支为例。 +本仓库已有可由服务器获取的 `main` 分支。后续部署仍必须由项目维护者先审阅本地变更、手动 commit 并 push 到远程仓库;本项目不会自动提交、推送或迁移服务器数据。以下命令以发布 `main` 分支为例。 -在开发机提交前先检查暂存区;当前已有两份用户 Excel 处于暂存状态,`git commit` 会把它们一并提交,除非维护者明确取消暂存。不要把 `.env` 或被忽略的原始 SQL 强制加入 Git: +在开发机提交前先检查暂存区,不要把 `.env` 或被忽略的原始 SQL 强制加入 Git: ~~~bash cd /Users/andy/IdeaProjects/fire-safety-ymd git status --short git diff --cached --stat # 审阅后通过 IDE 或逐项执行 git add,只暂存确定要发布的路径。 -git commit -m 'bootstrap fire-safety test deployment' +git commit git push -u origin main ~~~ @@ -131,7 +131,7 @@ FIRE_SAFETY_POSTGIS_EXPECTED_SRID=4326 - FIRE_SAFETY_CHAT_COMPAT_APP_ID 是公开路径标识,不是 Secret;它必须与 Nginx 的精确 location = /api/v1/apps//completion 完全一致。 - 使用 FIRE_SAFETY_MCP_SCOPE_MODE=all 时,FIRE_SAFETY_MCP_ALLOWED_TOWNS 必须保持为空。all 是服务账号级的固定查询表范围,不是最终用户级授权。 - FIRE_SAFETY_POSTGIS_MIGRATION_DSN 不应配置给运行服务;迁移凭证只供一次性迁移命令使用,完成后应移除。 -- FIRE_SAFETY_HTTP_ADDR 在容器内应为 :8080,安全边界由 Compose 的 127.0.0.1:8080:8080 和宿主机 Nginx 提供;不要在 Compose 场景设为容器内的 127.0.0.1:8080。 +- FIRE_SAFETY_HTTP_ADDR 在容器内应为 :8080,安全边界由 Compose 的 127.0.0.1:16587:8080 和宿主机 Nginx 提供;不要在 Compose 场景设为容器内的 127.0.0.1:8080。 - 不要用没有 --quiet 的 docker compose config 或 docker inspect 把完整环境渲染到终端、CI 日志或工单;检查 .env 权限仍为 600。 ## 4. 容器访问现有 PostgreSQL/PostGIS @@ -163,7 +163,7 @@ docker compose build --pull docker compose up -d docker compose ps docker compose logs --tail=100 api -curl --fail http://127.0.0.1:8080/health +curl --fail http://127.0.0.1:16587/health ~~~ 预期结果:容器为 Up(健康状态由 Compose 显示),health 返回 HTTP 200;有限日志不应出现 DSN、密码、Token 或 API Key。docker compose config --quiet 只验证配置,不输出展开后的 Secret。若 Compose 不支持 --quiet,升级 Compose 或使用不会回显结果的等价校验方式。 @@ -179,7 +179,7 @@ docker compose logs --tail=200 api ## 6. 安装/替换宿主机 Nginx 配置 -仓库模板为 deploy/nginx/fire-safety-ymd.conf.example,不含真实 Secret。它把精确 Chat 兼容路径、/mcp 和可选 /health 反代到 127.0.0.1:8080,其他路径返回 404;详细 SSE 边界见 nginx-public-entry.md。 +仓库模板为 deploy/nginx/fire-safety-ymd.conf.example,不含真实 Secret。它把精确 Chat 兼容路径、/mcp 和可选 /health 反代到 127.0.0.1:16587,其他路径返回 404;详细 SSE 边界见 nginx-public-entry.md。 先只查找拥有 agent.nianxx.com 的配置文件名,避免使用 nginx -T 把旧文件中的 DashScope Key 打到终端: @@ -207,7 +207,7 @@ sudo vi /etc/nginx/conf.d/fire-safety-ymd.conf 编辑时完成以下非 Secret 替换: - 将 replace-with-fire-safety-app-id 替换为 .env 中的 FIRE_SAFETY_CHAT_COMPAT_APP_ID。 -- 确认证书路径、域名和上游 127.0.0.1:8080 符合测试服务器。 +- 确认证书路径、域名和上游 127.0.0.1:16587 符合测试服务器。 - 保留精确 location、SSE 的 proxy_buffering off/超时设置和其他路径的 404;不要恢复旧配置的 location /、DashScope proxy_pass、Authorization Key 或 Nginx if Token 比较。 - limit_req_zone 必须位于 Nginx http 上下文;模板假定由 conf.d/*.conf 在 http {} 中 include。若 include 层级不同,把指令移到合法的 http 上下文。 diff --git a/docs/project/operations/nginx-public-entry.md b/docs/project/operations/nginx-public-entry.md index 90dd3c2..8bdb1fe 100644 --- a/docs/project/operations/nginx-public-entry.md +++ b/docs/project/operations/nginx-public-entry.md @@ -4,7 +4,7 @@ | --- | --- | | 目标 | 让 `agent.nianxx.com` 通过 HTTPS 访问本项目的兼容对话接口和 MCP | | 状态 | 示例配置;公网机器、证书、网络白名单和真实鉴权仍待联调 | -| 上游 | 仅反代本机 `127.0.0.1:8080` | +| 上游 | 仅反代本机 `127.0.0.1:16587`;容器内部仍监听 8080 | ## 1. 与旧配置的变化 @@ -13,7 +13,8 @@ ```text 公网 HTTPS -> Nginx(TLS、精确路径、限流、SSE 传输设置) - -> 127.0.0.1:8080(fire-safety-ymd) + -> 127.0.0.1:16587(Docker 发布端口) + -> 容器内 :8080(fire-safety-ymd) -> Go 侧校验 xtoken / MCP Bearer ``` @@ -35,7 +36,7 @@ Nginx 不再调用 DashScope,也不保存或注入 SuperAgent Open API Key、C 1. 把 `location = /api/v1/apps/replace-with-fire-safety-app-id/completion` 中的占位符替换为安全的 app ID。 2. 该 app ID 必须与 Go 服务的 `FIRE_SAFETY_CHAT_COMPAT_APP_ID` 完全一致;两处不一致会导致请求被拒绝。 3. 确认证书路径 `/cert/agent.nianxx.com.pem` 和 `/cert/agent.nianxx.com.key` 在公网机器上存在,并由 Nginx 进程可读。 -4. 直接在宿主机运行 Go 时,确认服务只监听 `127.0.0.1:8080`;使用本仓库 Compose 时,容器内监听 `:8080`,但端口映射必须保持为 `127.0.0.1:8080:8080`。两种方式都不要把 8080 或 PostgreSQL 5432 暴露到公网。 +4. 直接在宿主机运行 Go 时,应选择未占用的回环端口并同步修改 Nginx upstream;使用本仓库 Compose 时,容器内监听 `:8080`,端口映射保持为 `127.0.0.1:16587:8080`。不要把 16587、容器 8080 或 PostgreSQL 5432 暴露到公网。 5. 按环境配置 DNS、云防火墙/安全组和 SuperAgent 对 `/mcp` 的来源 IP/TLS 要求;这些部署事实尚未由本项目验证。 `limit_req_zone` 必须位于 Nginx `http` context,不能放进 `server` 或 `location`。示例文件假定它被 `conf.d/*.conf` 从 `http {}` 中 include;如果部署系统不是这样 include,应把两条 `limit_req_zone` 指令单独移到 `http {}`,并保留 `server`/`upstream` 在合法上下文。 @@ -45,9 +46,9 @@ Nginx 不再调用 DashScope,也不保存或注入 SuperAgent Open API Key、C 在服务器的未提交 Secret 管理方式(例如权限收紧的 `.env`、systemd EnvironmentFile 或容器 Secret)中配置,不要写入 Nginx 文件或 Git: ```text -# 宿主机直接运行时使用 127.0.0.1:8080;Compose 会覆盖为容器内的 :8080, -# 并只把端口发布到宿主机回环地址。 -FIRE_SAFETY_HTTP_ADDR=127.0.0.1:8080 +# Compose 会覆盖为容器内的 :8080,并发布到宿主机回环地址 16587。 +# 若直接在宿主机运行,则使用 127.0.0.1:16587 并保持 Nginx upstream 一致。 +FIRE_SAFETY_HTTP_ADDR=127.0.0.1:16587 FIRE_SAFETY_SUPERAGENT_ENABLED=true FIRE_SAFETY_SUPERAGENT_BASE_URL=https:// diff --git a/docs/project/security-access-control-boundary.md b/docs/project/security-access-control-boundary.md index d173b19..3dfc74d 100644 --- a/docs/project/security-access-control-boundary.md +++ b/docs/project/security-access-control-boundary.md @@ -71,7 +71,7 @@ MCP 第一阶段已按以下只读边界实现: - 应用数据库角色使用最小权限;MCP 查询角色默认只授予必要表或视图的 `SELECT`。 - 数据迁移凭证与运行时只读凭证分离;2026-09-05 的一次性 SRID 迁移使用表所有者执行,完成后不应保留在应用部署环境。 - Compose 从未提交的 `.env` 注入运行时配置,但会把 `FIRE_SAFETY_POSTGIS_MIGRATION_DSN` 强制覆盖为空;镜像构建不得复制 `.env`、证书、SQL 导出或 Excel 数据。 -- 应用容器只发布宿主机 `127.0.0.1:8080`,公网只经 Nginx 的 HTTPS 精确路径进入;8080 和数据库端口不得加入公网安全组。 +- 应用容器内监听 8080,只发布宿主机 `127.0.0.1:16587`,公网只经 Nginx 的 HTTPS 精确路径进入;16587、容器 8080 和数据库端口不得加入公网安全组。 - 使用参数化查询,不把用户或模型内容拼入 SQL、表名、排序或空间表达式。 - 设置连接、查询和 statement timeout;限制半径、结果数和空间复杂度,防止昂贵查询。 - 优先通过项目领域视图或明确映射屏蔽历史物理表名和不一致字段。