## 结果 四容器编排从 6 个 service 降到 5 个:`postgres` / `redis` / `business` / `gateway` 常驻 + `migrate` 一次性。**常驻容器 5 → 4**,实测直连 `127.0.0.1:4000|3000/health` 均 200。 ## 为什么现在做 `docker-compose.prod.yml` 里早就写着"生产不启动自带 nginx 容器,接入层交给 1Panel OpenResty",只是用 `profiles: ["never"]` 停用的。也就是说**生产本来就没这个容器**, 默认文件里留着它反而让两条路径分叉:本地开发跑一套、生产跑另一套,`nginx.conf` 只服务前者。现在两套文件对齐,反代只在宿主一处。 ## 三个必须处理的连带问题(都不是删几行就完事) **① `&logging` 锚点原本挂在 nginx service 里**,被另外 5 个 service 用 `*logging` 引用。直接删块会让 Compose 报 YAML 锚点未定义,而**报错点在引用的那几行、不在 被删的地方**。已把它提到顶层 `x-logging:` 扩展字段(Compose 支持),并把这个坑 写进注释。 **② prod 覆盖里那段 `nginx: profiles: ["never"]` 会变成悬空引用**(服务已不存在), 一并删除并改写注释。 **③ `watchdog.sh` 探的 `/healthz` 原本是 nginx 容器提供的虚拟端点。** 删掉后它会 恒报 `entry:404` —— 一个"服务其实好好的但监控一直叫"的假故障。已把探针语义改成 "接入层活着",并在 404 时把最常见成因写进告警文本(宿主反代没配 /healthz)。 ## 宿主反代模板 `deploy/nginx.host.conf.example`(替代原来的 `deploy/nginx.conf`),关键差异: upstream 从 `gateway:3000` / `business:4000` 改为 `127.0.0.1:3000` / `127.0.0.1:4000` —— 容器服务名**在宿主上根本不解析**,照抄旧配置会 `host not found in upstream`。 四条承载性指令原样保留,且写清了缺每一条的**症状**(都不是 502): - `proxy_http_version 1.1` + `Upgrade`/`Connection` → 缺了 WebSocket 握手失败 - `proxy_read_timeout 600s` → 缺了长连接 60 秒被无声掐断 - `proxy_buffering off` → 缺了画面不实时(数据被攒住) - `/relay/` 的 `proxy_request_buffering off` → 缺了"文件不落盘"变成假话 配置已用真 `nginx -t` 校验(`nginx:1.27-alpine`,`syntax is ok / test is successful`), 不是靠肉眼或 grep 判断。 ## 护栏:把"搬到宿主"这件事本身变成可验证的 `tests/dockerfile-coverage-test.js` 新增 7 条:模板存在、四条承载性指令各一条、 upstream 必须是回环而非 Docker 服务名、以及一条**负向**断言 —— 四容器编排里不许 再冒出 `nginx:` 服务(防"顺手加回来"造成两处真相)。 不加这段的话,宿主模板被删或被简化**不会有任何测试变红**,而症状是"页面能开但画面 不刷新",从现象很难倒推回配置。 测试:`dockerfile-coverage` **60/0**、`claim-proof` **57/0**。 ## README 现状描述(目录树 / 端口表 / 起栈步骤)已改。**历史段落不改写**: - "5 容器 healthy、经 nginx :80 入口"那句加"时代注记",说明那是当时形态; - "坑 B:nginx 强依赖证书"整段加抬头说明容器已移除,但**过程与教训原样保留** —— 那两条坑(硬引用可选文件导致 clone 必崩、Compose ports 是拼接语义)在宿主反代上 一样成立,只是换了文件。
88 lines
2.4 KiB
Plaintext
88 lines
2.4 KiB
Plaintext
# PMon 接入层 · 生产 HTTPS 配置模板
|
||
#
|
||
# 使用方法:
|
||
# 1) 将证书放入 deploy/certs/:
|
||
# deploy/certs/fullchain.pem
|
||
# deploy/certs/privkey.pem
|
||
# 2) 备份默认配置并启用本模板:
|
||
# cd deploy
|
||
# cp nginx.conf nginx.conf.bak
|
||
# cp nginx.ssl.conf.example nginx.conf
|
||
# 3) 重启接入层:
|
||
# docker compose up -d nginx
|
||
#
|
||
# 证书目录已被 .gitignore 排除,切勿把私钥提交入库。
|
||
|
||
upstream inkwatch_gateway {
|
||
server 127.0.0.1:3000 max_fails=2 fail_timeout=10s;
|
||
keepalive 64;
|
||
}
|
||
|
||
upstream inkwatch_business {
|
||
server 127.0.0.1:4000 max_fails=2 fail_timeout=10s;
|
||
keepalive 16;
|
||
}
|
||
|
||
map $http_upgrade $connection_upgrade {
|
||
default upgrade;
|
||
'' close;
|
||
}
|
||
|
||
# 80:仅保留探活,其余 301 跳转 HTTPS
|
||
server {
|
||
listen 80 default_server;
|
||
server_name _;
|
||
location = /healthz { return 200 'ok'; add_header Content-Type text/plain; }
|
||
location / { return 301 https://$host$request_uri; }
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl;
|
||
http2 on;
|
||
server_name _;
|
||
|
||
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
||
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
||
ssl_protocols TLSv1.2 TLSv1.3;
|
||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||
ssl_session_cache shared:SSL:10m;
|
||
ssl_session_timeout 1h;
|
||
|
||
location = /healthz {
|
||
proxy_pass http://inkwatch_gateway/health;
|
||
proxy_set_header Host $host;
|
||
}
|
||
|
||
# Socket.io 长连接
|
||
location /socket.io/ {
|
||
proxy_pass http://inkwatch_gateway;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection $connection_upgrade;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
|
||
proxy_read_timeout 600s;
|
||
proxy_send_timeout 600s;
|
||
proxy_connect_timeout 10s;
|
||
proxy_buffering off;
|
||
}
|
||
|
||
# 业务 REST 接口
|
||
location /api/ {
|
||
proxy_pass http://inkwatch_business;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
client_max_body_size 256k;
|
||
}
|
||
|
||
location /health {
|
||
proxy_pass http://inkwatch_gateway/health;
|
||
}
|
||
}
|