From 7980c1922a21cec197673fc9ced342615f727a85 Mon Sep 17 00:00:00 2001 From: whm <973418690@qq.com> Date: Mon, 23 Mar 2026 17:57:09 +0800 Subject: [PATCH] =?UTF-8?q?chore(compose):=20web=20=E4=BB=85=E4=BF=9D?= =?UTF-8?q?=E7=95=99=20public=20=E6=8C=82=E8=BD=BD=EF=BC=8C=E6=8E=A8?= =?UTF-8?q?=E5=B9=BF=E8=B5=B0=20dist/API=EF=BC=9B=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E4=BB=85=20yh=5Fnginx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Made-with: Cursor --- deploy/README.md | 2 +- deploy/web/default.conf | 11 ++--------- docker-compose.yml | 4 +--- nginx/README.md | 2 +- nginx/web.conf | 9 +-------- verify-root/README.md | 2 +- web/public/README.md | 2 +- web/src/data/promotionSocial.js | 2 +- web/src/utils/promotionAssets.js | 2 +- 9 files changed, 10 insertions(+), 26 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index d5cb348..c391d2b 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,4 +1,4 @@ -# deploy 目录(挂目录 + 替换文件部署) +# deploy 目录(与 api 相同:仅替换构建产物;`web` 容器除 `web/public` 外不挂源码目录) - **deploy/web/dist**:前台构建产物,由 `pull-and-restart.sh` 生成;替换此目录内容即可更新前台。 - **deploy/admin/dist**:后台构建产物,同上。后台 Vite 通过 `@yh-web` 引用 `../web/src`(如积木 `BlockRenderer`),用 Docker 单目录挂载 `admin` 时会构建失败,须挂载**项目根**再在 `admin` 下执行 `npm run build`(见 `pull-and-restart.sh`)。 diff --git a/deploy/web/default.conf b/deploy/web/default.conf index 754a18c..11d2ea9 100644 --- a/deploy/web/default.conf +++ b/deploy/web/default.conf @@ -4,13 +4,7 @@ server { root /usr/share/nginx/html; index index.html; - # 域名/微信等验证文件:用 root+URI,勿用「正则 + alias $1」(易 403);文件放宿主机 ./verify-root/ - location ~ ^/[A-Za-z0-9._-]+\.(txt|html|xml)$ { - root /verify-root; - try_files $uri =404; - default_type text/plain; - add_header Cache-Control "no-store"; - } + # 域名/微信等验证文件:由外层 yh_nginx(443)直接 root /verify-root 提供,本容器不再挂载 verify-root # 静态资源必须真实存在,避免错误回退成 index.html 导致白屏 location ^~ /assets/ { @@ -47,8 +41,7 @@ server { add_header Cache-Control "public, max-age=604800"; } - # 推广素材:含视频/封面等大文件,浏览器可长期缓存减轻二次访问流量 - # 宿主机 ./web/promotion 挂载覆盖本路径,改素材后依赖 max-age 到期或用户强刷 + # 推广素材:来自构建产物 deploy/web/dist/promotion(pull-and-restart 从 web/promotion rsync);后台上传走 /api/web/.../promotion-media/ location ^~ /promotion/ { try_files $uri =404; expires 7d; diff --git a/docker-compose.yml b/docker-compose.yml index 02dc329..7645a98 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,16 +28,14 @@ services: networks: - yh_net - # 静态文件由脚本构建到 deploy/web/dist;另挂载源码目录便于热更新(改宿主机文件即生效,无需重建 dist) + # 静态文件仅 deploy/web/dist;与 api 一致不挂源码目录。仅额外挂载 web/public(logo、social 二维码等) web: image: ${REGISTRY_MIRROR:-docker.m.daocloud.io/library/}nginx:alpine container_name: yh_web volumes: - ./deploy/web/dist:/usr/share/nginx/html:ro - - ./web/promotion:/usr/share/nginx/html/promotion:ro - ./web/public:/var/www/yh-public:ro - ./deploy/web/default.conf:/etc/nginx/conf.d/default.conf:ro - - ./verify-root:/verify-root:ro networks: - yh_net diff --git a/nginx/README.md b/nginx/README.md index f987a38..c939939 100644 --- a/nginx/README.md +++ b/nginx/README.md @@ -56,7 +56,7 @@ sudo systemctl reload nginx **/api/health 或 /admin/ 返回 404 时**:在服务器执行 `ss -tlnp | grep 443`,看 443 是宿主机 nginx 还是 docker。若是宿主机 nginx,要么停用该站点配置让 compose 独占 443(方式 A),要么改为方式 B(compose 用 8443,宿主机反代到 8443)。 -**验证文件热加载**:如果只需要把某些根目录验证文件上线,放到项目根目录的 `verify-root/` 里即可,`web` 容器会把它挂载为 `/verify-root`,并直接从网站根路径提供这些 `.txt/.html/.xml` 文件。修改文件后不需要重建 `web` 镜像,只要文件保存到宿主机上就会立刻生效。 +**验证文件热加载**:把验证文件放到项目根目录的 `verify-root/` 即可;compose 内 **`yh_nginx`** 挂载该目录并在 **443** 上直接 `root /verify-root` 提供(见 `nginx/yuheng.docker.conf.tpl`)。`reload` 后生效;若仅改文件,可 `docker compose restart nginx`。 ## 4. 新服务器首次安装 Nginx diff --git a/nginx/web.conf b/nginx/web.conf index b4e4d5a..3e30a99 100644 --- a/nginx/web.conf +++ b/nginx/web.conf @@ -1,16 +1,9 @@ -# 供 compose 中 web 容器使用:宿主机挂载 web/dist 与 verify-root,仅提供静态与 SPA 回退 +# 供 compose 中 web 容器使用:与 deploy/web/default.conf 同步;验证文件仅外层 yh_nginx 处理 server { listen 80; root /usr/share/nginx/html; index index.html; - location ~ ^/[A-Za-z0-9._-]+\.(txt|html|xml)$ { - root /verify-root; - try_files $uri =404; - default_type text/plain; - add_header Cache-Control "no-store"; - } - location ^~ /assets/ { try_files $uri =404; access_log off; diff --git a/verify-root/README.md b/verify-root/README.md index 3f940fe..05a2dd1 100644 --- a/verify-root/README.md +++ b/verify-root/README.md @@ -8,4 +8,4 @@ - 文件权限:`chmod 644 *.txt`,目录 `chmod 755`(或 `chmod -R a+rX .`) - 容器需能读挂载目录(Podman/SELinux 可尝试 `:Z` 或 `chcon`,见部署文档) -- 确保 **`docker-compose` 中 `yh_nginx` 与 `yh_web` 均挂载 `./verify-root:/verify-root`** +- 确保 **`docker-compose` 中 `yh_nginx`(443 入口)挂载 `./verify-root:/verify-root`**;`yuheng.docker.conf.tpl` 在 443 上直接用该目录提供验证文件,**不再**要求 `yh_web` 挂载 diff --git a/web/public/README.md b/web/public/README.md index 152fcce..6dda65d 100644 --- a/web/public/README.md +++ b/web/public/README.md @@ -5,7 +5,7 @@ ## 可选子目录 `social/` 「关注我们」二维码可放在 **`public/social/`**,访问路径为 **`/social/文件名`**。 -若此处没有对应文件,前端会自动尝试 **`/promotion/social/`**(`web/promotion/social/` 挂载)。 +若此处没有对应文件,前端会自动尝试 **`/promotion/social/`**(`deploy/web/dist/promotion`,由 `pull-and-restart.sh` 从 `web/promotion` 同步)或 **`/api/web/sites/{site_id}/promotion-media/...`**。 ## 根目录文件示例 diff --git a/web/src/data/promotionSocial.js b/web/src/data/promotionSocial.js index d860957..43559a9 100644 --- a/web/src/data/promotionSocial.js +++ b/web/src/data/promotionSocial.js @@ -4,7 +4,7 @@ import { promotionUrl } from '../utils/promotionAssets' * 「关注我们」二维码图加载顺序(前者 404 时 img @error 自动换下一项): * 1. /social/ → web/public/social/(Docker 挂载 /var/www/yh-public/social) * 2. / → web/public/ 根目录 - * 3. /promotion/social/ → web/promotion/social/(挂载或 dist) + * 3. /promotion/social/ → deploy/web/dist/promotion(构建/部署脚本同步,非容器挂载) */ export function socialFollowImageCandidates(filename) { return [`/social/${filename}`, `/${filename}`, promotionUrl(`social/${filename}`)] diff --git a/web/src/utils/promotionAssets.js b/web/src/utils/promotionAssets.js index b586e47..6f2fbf3 100644 --- a/web/src/utils/promotionAssets.js +++ b/web/src/utils/promotionAssets.js @@ -2,7 +2,7 @@ import { apiBase } from '../config' /** * 推广素材根路径。开发时由 Vite 映射到 web/promotion; - * 首页产品视频见 `buildPromotionVideosAsync`:同域静态存在则 `/promotion/...`,否则 `promotionMediaApiUrl`。 + * 生产:同域静态为 dist 内 `/promotion/...`(部署脚本 rsync),否则 `promotionMediaApiUrl`(API uploads)。 */ export function promotionUrl(relativePath) { const parts = String(relativePath).split('/').filter(Boolean)