docs: 更新导览站点端口与证书部署说明
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-22 20:17:53 +08:00
parent 5d0c38e726
commit d07d68af0a

View File

@@ -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 静态测试页面 + Lets Encrypt HTTPS 证书
- 页面地址:<https://guide.whaoyue.com:4433/>
- 首次部署日期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 跳转
- 验证 Lets 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/` 路径仍保留,但 Lets 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`
证书颁发机构Lets 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'
```
Lets 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`, Lets 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 |