719 lines
24 KiB
Markdown
719 lines
24 KiB
Markdown
# 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 证书
|
||
- 页面地址:<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 跳转
|
||
- 验证 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 |
|