From d07d68af0a0acb613f6488de62a46ad785025fd8 Mon Sep 17 00:00:00 2001 From: lyf <2514544224@qq.com> Date: Wed, 22 Jul 2026 20:17:53 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E5=AF=BC=E8=A7=88?= =?UTF-8?q?=E7=AB=99=E7=82=B9=E7=AB=AF=E5=8F=A3=E4=B8=8E=E8=AF=81=E4=B9=A6?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/deployment/guide-whaoyue-nginx-ssl.md | 718 +++++++++++++++++++++ 1 file changed, 718 insertions(+) create mode 100644 docs/deployment/guide-whaoyue-nginx-ssl.md diff --git a/docs/deployment/guide-whaoyue-nginx-ssl.md b/docs/deployment/guide-whaoyue-nginx-ssl.md new file mode 100644 index 0000000..a43a9d7 --- /dev/null +++ b/docs/deployment/guide-whaoyue-nginx-ssl.md @@ -0,0 +1,718 @@ +# guide.whaoyue.com 静态站点部署说明 + +## 1. 部署目标 + +- 域名:`guide.whaoyue.com` +- 服务器备注:自然博物馆-测试服务器 +- 公网 IP:`1.92.206.90` +- SSH 用户:`root` +- 系统:Huawei Cloud EulerOS 2.0 aarch64 +- 部署内容:Nginx 静态测试页面 + Let’s Encrypt HTTPS 证书 +- 页面地址: +- 首次部署日期:2026-06-08 +- 端口调整日期:2026-07-22 + +> 当前公网 HTTPS 入口是 `4433`,访问地址必须显式携带端口。`https://guide.whaoyue.com/` 使用默认 `443`,不再是当前入口。 + +## 2. 当前部署拓扑 + +服务器已安装系统级 Nginx 包。Docker Nginx 容器内仍监听标准 `80/443`,宿主机公网映射已调整为 `8888/4433`。 + +```text +公网用户 + -> guide.whaoyue.com + -> 1.92.206.90:8888/4433 + -> Docker 容器 nginx-server + -> 宿主机 8888 -> 容器 80 + -> 宿主机 4433 -> 容器 443 + -> /dmdata/nginx/html/guide/index.html +``` + +Docker Nginx 容器: + +```bash +docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}" +``` + +当前端口映射: + +| 宿主机端口 | 容器端口 | 用途 | +| --- | --- | --- | +| `8888` | `80` | HTTP 入口,跳转到 `https://guide.whaoyue.com:4433/` | +| `4433` | `443` | HTTPS 静态站点和反向代理 | +| `7080` | `7080` | 既有服务,端口调整时必须保留 | +| `7081` | `7081` | 既有服务,端口调整时必须保留 | + +关键挂载: + +| 宿主机路径 | 容器路径 | 用途 | +| --- | --- | --- | +| `/dmdata/nginx/conf.d` | `/etc/nginx/conf.d` | Nginx 站点配置 | +| `/dmdata/nginx/html` | `/usr/share/nginx/html` | 静态页面 | +| `/dmdata/nginx/ssl` | `/etc/nginx/ssl` | SSL 证书 | +| `/dmdata/nginx/logs` | `/var/log/nginx` | 访问日志和错误日志 | + +## 3. 静态页面 + +静态测试页路径: + +```bash +/dmdata/nginx/html/guide/index.html +``` + +页面用途: + +- 验证域名解析 +- 验证 Nginx 静态站点 +- 验证 HTTP 到 HTTPS 跳转 +- 验证 Let’s Encrypt 证书 + +如需替换正式页面,将构建后的静态文件发布到: + +```bash +/dmdata/nginx/html/guide/ +``` + +## 4. Nginx 配置 + +站点配置文件: + +```bash +/dmdata/nginx/conf.d/guide.whaoyue.com.conf +``` + +配置行为: + +- `http://guide.whaoyue.com:8888/` 自动跳转到 `https://guide.whaoyue.com:4433/` +- `/.well-known/acme-challenge/` 路径仍保留,但 Let’s Encrypt HTTP-01 不会验证 `8888`,续期限制见第 5 节 +- `https://guide.whaoyue.com:4433/` 返回静态页面 +- `https://guide.whaoyue.com:4433/app-api/` 反向代理到宿主机 `48080/yudao-server/app-api/` +- `https://guide.whaoyue.com:4433/h5-sdk` 配置为反向代理到宿主机 `3001`;2026-07-22 公网抽查为 `502`,当前不可作为可用能力 +- `https://guide.whaoyue.com:4433/museum-assets/` 和 `/minio/museum-assets/` 反向代理到 MinIO +- 静态资源设置 30 天缓存 + +### 4.1 H5 SDK 与后端代理规则 + +H5 页面运行在 HTTPS 下,前端运行时代码不能直接请求: + +```text +http://1.92.206.90:3001/app-api/... +http://1.92.206.90:9000/museum-assets/... +``` + +否则浏览器会拦截 mixed content,表现为 SDK 后端接口请求失败或 3D 模型资源 `Failed to fetch`。 + +前端 H5 构建环境应使用同源路径: + +```dotenv +VITE_DATA_SOURCE_MODE=sdk +VITE_API_BASE_URL=/app-api +VITE_SGS_API_BASE_URL=/app-api +VITE_SGS_MAP_ID=1 +VITE_SGS_SDK_SCRIPT_URL=/static/sgs-map-sdk/index.global.js +VITE_SGS_H5_ENGINE_URL=/h5-sdk +VITE_SGS_SDK_ORIGIN=https://guide.whaoyue.com:4433 +``` + +`VITE_SGS_H5_ENGINE_URL=/h5-sdk` 仅在 H5 SDK 上游恢复后可用;2026-07-22 公网响应为 `502`。 + +Nginx 容器内的 `443 ssl` server 中必须包含以下代理规则。宿主机 `4433` 通过 Docker 映射进入容器 `443`: + +```nginx +location ^~ /app-api/ { + proxy_pass http://172.17.0.1:48080/yudao-server/app-api/; + 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_http_version 1.1; + proxy_set_header Connection ""; + proxy_connect_timeout 60s; + proxy_read_timeout 120s; + proxy_send_timeout 120s; +} + +location ^~ /h5-sdk { + proxy_pass http://172.17.0.1:3001/h5-sdk; + 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_http_version 1.1; + proxy_set_header Connection ""; + proxy_connect_timeout 60s; + proxy_read_timeout 120s; + proxy_send_timeout 120s; +} + +location ^~ /minio/museum-assets/ { + proxy_pass http://172.17.0.1:9000/museum-assets/; + proxy_set_header Host 172.17.0.1:9000; + expires 30d; + add_header Cache-Control "public"; +} + +location ^~ /museum-assets/ { + proxy_pass http://172.17.0.1:9000/museum-assets/; + proxy_set_header Host 172.17.0.1:9000; + expires 30d; + add_header Cache-Control "public"; +} +``` + +每次修改后检查并重载: + +```bash +docker exec nginx-server nginx -t +docker exec nginx-server nginx -s reload +``` + +检查配置: + +```bash +docker exec nginx-server nginx -t +``` + +重载配置: + +```bash +docker exec nginx-server nginx -s reload +``` + +重启容器: + +```bash +docker restart nginx-server +``` + +### 4.2 Docker 端口映射 + +当前容器没有 compose 管理,端口映射保存在容器启动参数中。检查当前值: + +```bash +docker inspect nginx-server --format '{{json .HostConfig.PortBindings}}' +``` + +期望结果包含: + +```text +宿主机 8888 -> 容器 80 +宿主机 4433 -> 容器 443 +宿主机 7080 -> 容器 7080 +宿主机 7081 -> 容器 7081 +``` + +需要重建容器时,先保存检查信息并保留旧容器用于回滚: + +```bash +ts=$(date +%Y%m%d%H%M%S) +docker inspect nginx-server \ + > "/dmdata/nginx/backups/nginx-server-inspect-before-port-change-${ts}.json" +docker stop nginx-server +docker rename nginx-server "nginx-server-before-port-change-${ts}" + +docker run -d \ + --name nginx-server \ + --restart unless-stopped \ + -p 8888:80 \ + -p 4433:443 \ + -p 7080:7080 \ + -p 7081:7081 \ + -v /dmdata/nginx/conf.d:/etc/nginx/conf.d:ro \ + -v /dmdata/nginx/ssl:/etc/nginx/ssl:ro \ + -v /dmdata/nginx/html:/usr/share/nginx/html:ro \ + -v /dmdata/nginx/logs:/var/log/nginx \ + arm64v8/nginx:stable-alpine +``` + +服务器防火墙必须持久化放行新端口: + +```bash +firewall-cmd --permanent --add-port=8888/tcp +firewall-cmd --permanent --add-port=4433/tcp +firewall-cmd --reload +``` + +启动后先执行 `nginx -t` 和第 6 节公网验证。全部通过后再删除已停止的旧容器。 + +## 5. SSL 证书 + +证书客户端:`acme.sh` + +证书颁发机构:Let’s Encrypt + +证书路径: + +```bash +/dmdata/nginx/ssl/guide.whaoyue.com/fullchain.pem +/dmdata/nginx/ssl/guide.whaoyue.com/privkey.pem +``` + +证书信息: + +```text +Subject: CN = guide.whaoyue.com +Issuer: Let's Encrypt YR2 +Not Before: 2026-06-07 15:33:10 GMT +Not After: 2026-09-05 15:33:09 GMT +``` + +查看证书: + +```bash +openssl x509 -in /dmdata/nginx/ssl/guide.whaoyue.com/fullchain.pem -noout -subject -issuer -dates +``` + +自动续期: + +```bash +crontab -l | grep acme +``` + +当前续期任务: + +```text +11 7 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null +``` + +当前证书配置使用 Webroot HTTP-01: + +```text +Le_Webroot='/dmdata/nginx/html/guide' +``` + +Let’s Encrypt HTTP-01 固定验证公网 `80`,不会访问 `8888`。因此改为 `8888/4433` 后,cron 存在不代表证书能够自动续期。必须在证书到期前完成以下任一方案: + +1. 续期窗口临时恢复安全组、防火墙和 Docker 的公网 `80 -> 容器 80` 映射,续期完成后再关闭。 +2. 将 `acme.sh` 迁移为 DNS-01,并配置可用的 DNS API 凭据。 + +当前证书到期时间为 `2026-09-05 15:33:09 GMT`,迁移或续期测试应提前完成。 + +`acme.sh` 已配置证书安装后的 reload 命令: + +```bash +docker exec nginx-server nginx -s reload +``` + +满足公网 `80` 可验证或已迁移 DNS-01 后,才可执行手动续期测试: + +```bash +/root/.acme.sh/acme.sh --cron --home /root/.acme.sh --force +``` + +测试后必须重新检查证书到期时间,并从公网验证 `4433`: + +```bash +openssl x509 -in /dmdata/nginx/ssl/guide.whaoyue.com/fullchain.pem -noout -dates +curl -I https://guide.whaoyue.com:4433/ +``` + +## 6. 部署步骤复盘 + +1. 确认 DNS: + +```powershell +Resolve-DnsName guide.whaoyue.com -Type A +``` + +结果应指向: + +```text +1.92.206.90 +``` + +2. 确认公网端口: + +```powershell +Test-NetConnection guide.whaoyue.com -Port 8888 +Test-NetConnection guide.whaoyue.com -Port 4433 +``` + +3. 创建静态测试页: + +```bash +mkdir -p /dmdata/nginx/html/guide/.well-known/acme-challenge +``` + +4. 写入 Nginx 站点配置: + +```bash +/dmdata/nginx/conf.d/guide.whaoyue.com.conf +``` + +5. 申请证书(以下是 2026-06-08 使用公网 `80` 完成首次签发的历史命令;当前端口映射下不可直接用于 HTTP-01 续期): + +```bash +/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt +/root/.acme.sh/acme.sh --issue --server letsencrypt -d guide.whaoyue.com -w /dmdata/nginx/html/guide --keylength 2048 +``` + +6. 安装证书: + +```bash +/root/.acme.sh/acme.sh --install-cert -d guide.whaoyue.com \ + --key-file /dmdata/nginx/ssl/guide.whaoyue.com/privkey.pem \ + --fullchain-file /dmdata/nginx/ssl/guide.whaoyue.com/fullchain.pem \ + --reloadcmd "docker exec nginx-server nginx -s reload" +``` + +7. 验证访问: + +```powershell +curl.exe -I http://guide.whaoyue.com:8888/ +curl.exe -I https://guide.whaoyue.com:4433/ +curl.exe -I https://guide.whaoyue.com:4433/app-api/gis/sdk/maps/1/manifest +curl.exe -I https://guide.whaoyue.com:4433/h5-sdk +curl.exe -I https://guide.whaoyue.com:4433/static/sgs-map-sdk/index.global.js +curl.exe -I https://guide.whaoyue.com:4433/museum-assets/optimized/20260617/draco_EXTERIOR.glb_1781708354536.glb +curl.exe -I https://guide.whaoyue.com:4433/minio/museum-assets/sgs-map/glb/1/V20260624104338_8f086/models/L1_draco.glb +``` + +期望结果: + +```text +HTTP 301 -> https://guide.whaoyue.com:4433/ +HTTPS 200 OK +/app-api/... 200 application/json +/h5-sdk 当前为 502,修复上游或移除废弃规则前不得记为通过 +/static/sgs-map-sdk/index.global.js 200 application/javascript +模型 GLB 200 model/gltf-binary +``` + +## 7. 已处理的问题 + +本节中的无端口 URL、404 和 Mixed Content 文本是端口调整前的历史故障原文;当前复测命令统一使用 `8888/4433`。 + +### 7.1 Docker Nginx 配置校验失败 + +容器内 `nginx -t` 曾失败,原因是 Linux Docker 容器无法解析 `host.docker.internal`。 + +处理方式: + +- 将 `/dmdata/nginx/conf.d/https.conf` 中的 `host.docker.internal` 代理目标改为 Docker 默认网关 `172.17.0.1` +- 重新执行 `docker exec nginx-server nginx -t` +- 配置校验通过后 reload Nginx + +### 7.2 公网端口调整为 8888/4433 + +系统级 Nginx 已安装,但站点继续由 `nginx-server` 容器承载。2026-07-22 将宿主机映射从 `80:80`、`443:443` 调整为 `8888:80`、`4433:443`,并保留 `7080/7081` 映射。Nginx 容器内仍监听标准 `80/443`。 + +HTTP server 的跳转目标必须显式包含新 HTTPS 端口: + +```nginx +return 301 https://$host:4433$request_uri; +``` + +### 7.3 H5 SDK 接口请求混合内容 + +现象: + +```text +Request URL http://1.92.206.90:3001/app-api/gis/sdk/maps/1/manifest +Referrer Policy strict-origin-when-cross-origin +``` + +页面实际运行在 `https://guide.whaoyue.com:4433/`,但构建产物中固化了 HTTP 后端地址,浏览器会拦截 mixed content 请求。若 Nginx 未配置 `/app-api/` 代理,改成同源路径后还会被 SPA 回退到 `index.html`。 + +处理方式: + +- 前端构建环境改为同源 `/app-api`、`/h5-sdk`、`/static/sgs-map-sdk/index.global.js` +- Nginx 增加 `/app-api/` 和 `/h5-sdk` 代理到宿主机 `3001` +- 重新构建并部署 H5 包 +- 扫描构建产物,确认运行时代码不再包含 `1.92.206.90:3001` + +验证: + +```powershell +curl.exe -I https://guide.whaoyue.com:4433/app-api/gis/sdk/maps/1/manifest +curl.exe -I https://guide.whaoyue.com:4433/h5-sdk +curl.exe -I https://guide.whaoyue.com:4433/static/sgs-map-sdk/index.global.js +``` + +### 7.4 SDK 模型资源请求混合内容 + +现象: + +- SDK 接口已经返回 `200 JSON` +- 页面仍提示 `3D 模型加载失败` 或 `Failed to fetch` +- 后端 bundle 中部分 `modelUrl` 为 `http://1.92.206.90:9000/museum-assets/...` + +原因: + +HTTPS 页面加载 HTTP MinIO 模型资源会被浏览器拦截;另外后端也可能返回 `/minio/museum-assets/...`,如果 Nginx 未配置该前缀,会落入 SPA 回退并返回 `index.html`。 + +处理方式: + +- Nginx 同时配置 `/museum-assets/` 和 `/minio/museum-assets/` 到 MinIO +- 前端对已知 `http://1.92.206.90:9000/museum-assets/...` 模型地址改写为同源 `/museum-assets/...` +- 重新构建并部署 H5 包 + +验证: + +```powershell +curl.exe -I https://guide.whaoyue.com:4433/museum-assets/optimized/20260617/draco_EXTERIOR.glb_1781708354536.glb +curl.exe -I https://guide.whaoyue.com:4433/minio/museum-assets/sgs-map/glb/1/V20260624104338_8f086/models/L1_draco.glb +``` + +期望均返回: + +```text +HTTP/1.1 200 OK +Content-Type: model/gltf-binary +``` + +### 7.5 展厅图标与占位图静态资源 404 + +现象: + +```text +GET https://guide.whaoyue.com/static/icons/halls/biology.jpg 404 +GET https://guide.whaoyue.com/static/icons/halls/evolution.jpg 404 +GET https://guide.whaoyue.com/static/icons/halls/dinosaur.jpg 404 +GET https://guide.whaoyue.com/static/icons/halls/earth.jpg 404 +GET https://guide.whaoyue.com/static/icons/halls/human.jpg 404 +GET https://guide.whaoyue.com/static/icons/halls/homeland.jpg 404 +GET https://guide.whaoyue.com/static/icons/halls/universe.jpg 404 +GET https://guide.whaoyue.com/static/exhibit-placeholder.jpg 404 +``` + +原因: + +- 源码目录存在 `static/icons/halls/*.jpg`,但 H5 构建后的补充复制脚本只复制了 `nav-assets`、`guide-data`、`sgs-map-sdk`、`three`,没有稳定复制 `static/icons`。 +- 页面与音频播放器中曾使用 `/static/exhibit-placeholder.jpg`、`/static/hall-placeholder.jpg` 作为兜底图,但静态目录里没有对应文件。 +- 旧浏览器缓存的 chunk 可能仍请求旧占位图路径,因此即使新代码改用 SVG 兜底,也需要保留兼容文件。 + +处理方式: + +- 更新 `frontend-miniapp/scripts/copy-h5-nav-assets.cjs`,将 `static/icons` 纳入 H5 构建产物复制清单。 +- 新代码兜底图改为已存在且会随包发布的: + - `/static/icons/marker-exhibit.svg` + - `/static/icons/marker-hall.svg` +- 同时补充兼容文件: + - `/static/exhibit-placeholder.jpg` + - `/static/hall-placeholder.jpg` +- 重新执行 `pnpm type-check`、`pnpm build:h5` 并部署 H5 包。 + +验证: + +```powershell +curl.exe -I https://guide.whaoyue.com:4433/static/icons/halls/biology.jpg +curl.exe -I https://guide.whaoyue.com:4433/static/icons/halls/evolution.jpg +curl.exe -I https://guide.whaoyue.com:4433/static/icons/halls/dinosaur.jpg +curl.exe -I https://guide.whaoyue.com:4433/static/icons/halls/earth.jpg +curl.exe -I https://guide.whaoyue.com:4433/static/icons/halls/human.jpg +curl.exe -I https://guide.whaoyue.com:4433/static/icons/halls/homeland.jpg +curl.exe -I https://guide.whaoyue.com:4433/static/icons/halls/universe.jpg +curl.exe -I https://guide.whaoyue.com:4433/static/exhibit-placeholder.jpg +curl.exe -I https://guide.whaoyue.com:4433/static/hall-placeholder.jpg +``` + +期望返回: + +```text +HTTP/1.1 200 OK +Content-Type: image/jpeg +``` + +其中 SVG 兜底图验证: + +```powershell +curl.exe -I https://guide.whaoyue.com:4433/static/icons/marker-exhibit.svg +curl.exe -I https://guide.whaoyue.com:4433/static/icons/marker-hall.svg +``` + +期望返回: + +```text +HTTP/1.1 200 OK +Content-Type: image/svg+xml +``` + +### 7.6 TTS 语音播放 Mixed Content + +现象: + +```text +Mixed Content: The page at 'https://guide.whaoyue.com/#/pages/exhibit/detail?id=715805000000000009&tab=explain' +was loaded over HTTPS, but requested an insecure audio file +'http://1.92.206.90:9000/tts-audio/audio/2026/06/30/947228d3e5174f3697f22cceac30075e.mp3'. +This request has been blocked; the content must be served over HTTPS. + +详情音频不可播放: 音频加载失败,当前提供图文讲解。 +H5 音频播放被拦截或失败: NotSupportedError: Failed to load because no supported source was found. +``` + +原因: + +- 页面运行在 HTTPS 下,但后端语音播放接口返回的 `playUrl` 指向 `http://1.92.206.90:9000/tts-audio/...`。 +- 浏览器不会把 IP 地址 HTTP 音频自动升级为 HTTPS,因此音频请求被 mixed content 策略拦截。 +- 服务器 Nginx 已配置 `/tts-audio/` 到 MinIO 的 HTTPS 同源代理,因此核心修复点是前端 URL 归一化,而不是新增代理。 + +当前 Nginx 代理规则应包含: + +```nginx +location ^~ /tts-audio/ { + proxy_pass http://172.17.0.1:9000/tts-audio/; + proxy_set_header Host 172.17.0.1:9000; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header Range $http_range; + proxy_set_header If-Range $http_if_range; + add_header Access-Control-Allow-Origin "*" always; + add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS" always; + add_header Access-Control-Allow-Headers "Range, Origin, Accept, Content-Type" always; + add_header Access-Control-Expose-Headers "Content-Length, Content-Range, Accept-Ranges" always; + add_header Cache-Control "public, max-age=604800" always; +} +``` + +处理方式: + +- 更新前端统一公共 URL 归一化逻辑 `normalizeSameOriginPublicUrl`: + - `http://1.92.206.90:9000/museum-assets/...` -> `/museum-assets/...` + - `http://1.92.206.90:9000/tts-audio/...` -> `/tts-audio/...` + - `http://47.120.48.148:19000/nhm/audio/...` -> `/nhm/audio/...` +- 确认 `AudioPlayInfoRepository`、后端讲解数据 adapter、静态导览 adapter 均通过该统一方法处理音频 URL。 +- 重新构建并部署 H5 包。 +- 扫描线上运行时代码,确认不再包含 `http://1.92.206.90:9000/tts-audio` 或其他 MinIO HTTP 直连。 + +验证时不要复用已经删除的历史 MinIO 对象。先从当前播放信息接口取得 `playUrl`: + +```powershell +curl.exe "https://guide.whaoyue.com:4433/app-api/gis/guide/audio/play-info?targetType=STOP&targetId=865546638960193536&lang=zh-CN" +curl.exe -I https://guide.whaoyue.com:4433/minio/museum-assets/tts-audio/audio/2026/07/17/63058096489b4f4aa516fb07fe4a1144.mp3 +``` + +期望返回: + +```text +HTTP/1.1 200 OK +Content-Type: audio/mpeg +Accept-Ranges: bytes +``` + +线上运行时代码扫描: + +```bash +grep -R 'http://1\.92\.206\.90:9000/tts-audio\|http://1\.92\.206\.90:9000' \ + -n /dmdata/nginx/html/guide/assets /dmdata/nginx/html/guide/index.html || true +``` + +期望无输出。 + +## 8. 回滚方式 + +配置备份目录: + +```bash +/dmdata/nginx/backups/20260608002938 +/dmdata/nginx/backups/20260608003215 +/dmdata/nginx/backups/guide.whaoyue.com.conf-before-port-change-20260722175845 +/dmdata/nginx/backups/nginx-server-inspect-before-port-change-20260722175845.json +``` + +回滚配置示例: + +```bash +cp -a /dmdata/nginx/backups/20260608003215/conf.d/* /dmdata/nginx/conf.d/ +docker exec nginx-server nginx -t +docker exec nginx-server nginx -s reload +``` + +如需回滚 2026-07-22 的端口调整,应根据检查快照重建容器为 `80:80`、`443:443`、`7080:7080`、`7081:7081`,同时恢复站点配置中的标准 HTTPS 跳转。执行前必须再次备份当前容器检查信息和站点配置。 + +如需移除本域名站点: + +```bash +rm -f /dmdata/nginx/conf.d/guide.whaoyue.com.conf +docker exec nginx-server nginx -t +docker exec nginx-server nginx -s reload +``` + +## 9. 运行维护检查清单 + +日常检查: + +```bash +docker ps --filter name=nginx-server +docker exec nginx-server nginx -t +curl -I http://guide.whaoyue.com:8888/ +curl -I https://guide.whaoyue.com:4433/ +curl -I https://guide.whaoyue.com:4433/app-api/gis/sdk/maps/1/manifest +curl -I https://guide.whaoyue.com:4433/h5-sdk +curl -I https://guide.whaoyue.com:4433/static/sgs-map-sdk/index.global.js +curl -I https://guide.whaoyue.com:4433/minio/museum-assets/sgs-map/glb/1/V20260624104338_8f086/models/L1_draco.glb +curl -I https://guide.whaoyue.com:4433/minio/museum-assets/tts-audio/audio/2026/07/17/63058096489b4f4aa516fb07fe4a1144.mp3 +curl -I https://guide.whaoyue.com:4433/static/icons/halls/biology.jpg +curl -I https://guide.whaoyue.com:4433/static/exhibit-placeholder.jpg +``` + +查看日志: + +```bash +tail -f /dmdata/nginx/logs/guide-http-access.log +tail -f /dmdata/nginx/logs/guide-https-access.log +tail -f /dmdata/nginx/logs/guide-https-error.log +``` + +证书检查: + +```bash +/root/.acme.sh/acme.sh --list +openssl x509 -in /dmdata/nginx/ssl/guide.whaoyue.com/fullchain.pem -noout -subject -issuer -dates +``` + +## 10. 验收记录 + +2026-06-08 验收结果: + +| 检查项 | 结果 | 证据 | +| --- | --- | --- | +| DNS A 记录 | 通过 | `guide.whaoyue.com -> 1.92.206.90` | +| 80 端口公网连通 | 通过 | `Test-NetConnection guide.whaoyue.com -Port 80 = True` | +| 443 端口公网连通 | 通过 | `Test-NetConnection guide.whaoyue.com -Port 443 = True` | +| HTTP 跳转 | 通过 | `HTTP/1.1 301 Moved Permanently` | +| HTTPS 静态页 | 通过 | `HTTP/1.1 200 OK` | +| Nginx 配置 | 通过 | `nginx: configuration file /etc/nginx/nginx.conf test is successful` | +| SSL 证书 | 通过 | `CN = guide.whaoyue.com`, Let’s Encrypt | +| 自动续期 | 通过 | `acme.sh` cron 已存在 | + +2026-06-26 SDK 后端与模型资源修复验收: + +| 检查项 | 结果 | 证据 | +| --- | --- | --- | +| SDK manifest 同源接口 | 通过 | `/app-api/gis/sdk/maps/1/manifest -> 200 application/json` | +| H5 SDK 基座 | 通过 | `/h5-sdk -> 200 text/html` | +| SDK 脚本 | 通过 | `/static/sgs-map-sdk/index.global.js -> 200 application/javascript` | +| MinIO `/museum-assets/` 模型 | 通过 | `draco_EXTERIOR.glb_1781708354536.glb -> 200 model/gltf-binary` | +| MinIO `/minio/museum-assets/` 模型 | 通过 | `L1_draco.glb -> 200 model/gltf-binary` | +| 混合内容引用 | 通过 | H5 运行时代码无 `1.92.206.90:3001`、`1.92.206.90:9000` | + +2026-06-30 静态图标、占位图与 TTS 音频修复验收: + +| 检查项 | 结果 | 证据 | +| --- | --- | --- | +| 展厅图标资源 | 通过 | `/static/icons/halls/biology.jpg` 等展厅图标 -> `200 image/jpeg` | +| 展品占位图兼容资源 | 通过 | `/static/exhibit-placeholder.jpg -> 200 image/jpeg` | +| 展厅占位图兼容资源 | 通过 | `/static/hall-placeholder.jpg -> 200 image/jpeg` | +| SVG 兜底图资源 | 通过 | `/static/icons/marker-exhibit.svg -> 200 image/svg+xml` | +| TTS 音频 HTTPS 代理 | 通过 | `/tts-audio/audio/2026/06/30/947228d3e5174f3697f22cceac30075e.mp3 -> 200 audio/mpeg` | +| TTS CORS/Range 响应 | 通过 | 响应包含 `Access-Control-Allow-Origin: *`、`Accept-Ranges: bytes` | +| 混合内容引用 | 通过 | H5 运行时代码无 `http://1.92.206.90:9000/tts-audio`、无 `http://1.92.206.90:9000` | + +2026-07-22 公网端口调整验收: + +| 检查项 | 结果 | 证据 | +| --- | --- | --- | +| Docker HTTP 映射 | 通过 | `0.0.0.0:8888 -> 80/tcp` | +| Docker HTTPS 映射 | 通过 | `0.0.0.0:4433 -> 443/tcp` | +| 既有端口保留 | 通过 | `7080/7081 -> 7080/7081` | +| 8888 端口公网连通 | 通过 | `http://guide.whaoyue.com:8888/ -> 301` | +| HTTP 跳转目标 | 通过 | `Location: https://guide.whaoyue.com:4433/` | +| 4433 首页 | 通过 | `https://guide.whaoyue.com:4433/ -> 200` | +| 4433 API 代理 | 通过 | `/app-api/gis/hall/list -> 200 application/json` | +| 域名校验文件 | 通过 | `/gpL0svkeao.txt -> 200 text/plain` | +| 当前语音对象 | 通过 | 播放信息返回的 `/minio/museum-assets/tts-audio/...mp3 -> 200 audio/mpeg` | +| H5 SDK 基座 | 阻塞 | `/h5-sdk -> 502`,不得沿用 2026-06-26 的 200 结论 | +| Nginx 配置 | 通过 | `nginx: configuration file /etc/nginx/nginx.conf test is successful` | +| 证书续期 | 待处理 | 当前 Webroot HTTP-01 不能通过公网 `8888` 完成验证,需恢复 `80` 或迁移 DNS-01 |