Files
gdm-Servo-model/DEPLOY_STATIC.md
hukeehong fb2a3466c4 Document npm registry mirror and Docker named volumes for builds
Per Issue #2, the static build workflow now consistently uses:
- npm_config_registry env var to switch to npmmirror (China mainland)
- duoji-node-modules named volume (replaces --tmpfs to avoid noexec)
- duoji-npm-cache named volume (faster subsequent installs)
- npm ci --no-audit --no-fund (faster CI/deploy)
- caddy reload note: bind mounts require docker-compose up -d caddy
- volume cleanup commands (docker volume rm ...)
2026-08-18 10:19:36 +08:00

156 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 高徳乐 AI 舵机选型助手:静态部署说明
本项目提供纯静态构建方式。产品数据、图片、选型计算、筛选和弹窗交互都在浏览器中运行;网站运行时不需要 Node.js、数据库、API 或 Cloudflare Worker。
## 当前服务器的推荐方案
服务器已经有 Docker Compose 管理的 Caddy 网关,并且 Caddy 占用 80/443 端口。因此本项目应当:
1. 使用 `npm run build:static` 生成 `dist-static/`
2.`dist-static/` 同步到服务器静态目录。
3. 把静态目录以只读方式挂载到现有 Caddy 容器。
4. 在现有 Caddyfile 中增加 `duoji.dbpi.com.cn` 的站点配置。
不要为本项目另起 Nginx不要让新容器绑定 80/443也不要改动现有 `galderma-api``galderma-db` 容器。
## 给 Git AI 的部署任务
可以直接把下面这段话发给仓库里的 AI
> 请把本仓库部署为 `duoji.dbpi.com.cn` 的纯静态网站。不要执行 `npm run build`,不要启动 Vinext Server、Node.js 后端或 Cloudflare Worker请执行 `npm run build:static`,发布生成的 `dist-static/` 目录。服务器已有 Docker Compose 管理的 Caddy 网关80/443 端口不能抢占,也不要启动独立 Nginx 或新的 80 端口容器。请先检查现有 `/root/galderma/docker-compose.yml` 和 Caddyfile在 Caddy 服务中增加只读挂载 `/var/www/duoji:/srv/duoji:ro`,并增加仓库 `deploy/Caddyfile.duoji` 中的站点配置。构建时服务器没有 Node.js使用一次性 `node:22-alpine` 容器构建,并通过环境变量 `npm_config_registry=https://registry.npmmirror.com` 切换到中国大陆 npm 镜像(官方源经常连不上);用两个 Docker named volume 分别隔离 `node_modules``duoji-node-modules`,解决 `tmpfs` 默认 `noexec` 导致 esbuild 执行失败的问题)和 npm 缓存(`duoji-npm-cache`,加快后续依赖安装)。修改前备份 Caddy 配置,修改后先校验配置,再只重载 Caddybind mount 改动必须重启 caddy 容器才生效(`caddy reload` 不会重挂 volume实际影响约 3 秒。不要改动 galderma-api、galderma-db 和现有站点不要把密码、SSH 密钥或 token 写入仓库。最后用 curl 检查首页、产品图片和 HTTPS。
## 构建静态文件
如果服务器有 Node.js
```bash
npm ci --no-audit --no-fund
npm run build:static
```
如果服务器没有 Node.js使用一次性 Docker 构建容器。该方式不会在宿主机留下 `node_modules`,并通过环境变量切换 npm 镜像源以适配中国大陆网络环境:
```bash
docker volume create duoji-node-modules
docker volume create duoji-npm-cache
docker run --rm \
-v "$PWD":/src \
-v duoji-node-modules:/src/node_modules \
-v duoji-npm-cache:/root/.npm \
-w /src \
-e npm_config_registry=https://registry.npmmirror.com \
node:22-alpine \
sh -lc 'npm ci --no-audit --no-fund && npm run build:static'
```
### 为什么这样设计
- **`npm_config_registry` 环境变量** 而不是 `npm config set`:避免在仓库或容器里写死镜像配置;非中国大陆环境不传这个环境变量就自动走官方源。
- **named volume `duoji-node-modules`** 替代 `--tmpfs`tmpfs 默认 `noexec`,会导致 esbuild 的 postinstall 可执行文件无法运行named volume 既隔离宿主机又支持可执行权限。
- **named volume `duoji-npm-cache`** 缓存 `/root/.npm`:第二次及以后的构建会复用缓存,`npm ci` 显著加快(从几十秒降到几秒)。注意:`npm ci` 仍会重建 `node_modules`(不修改 package-lock加速主要来自缓存元数据`node_modules` volume 主要用来隔离宿主机并解决执行权限问题。
- **`--no-audit --no-fund`**:跳过 npm 审计和赞助信息,加快 CI/部署速度。
### 清理构建缓存
需要彻底清理时执行:
```bash
docker volume rm duoji-node-modules
docker volume rm duoji-npm-cache
```
构建完成后,网站文件位于 `dist-static/`,入口是 `dist-static/index.html`。当前静态入口不依赖 `app/layout.tsx` 的动态 metadata因此不要用 `npm run build` 代替 `npm run build:static`
## 与现有 Caddy 共存
### 1. 同步静态文件
以下路径是示例,实际执行时让部署 AI 先确认服务器目录和权限:
```bash
sudo mkdir -p /var/www/duoji
sudo rsync -a --delete dist-static/ /var/www/duoji/
```
### 2. 给 Caddy 服务增加只读目录挂载
在现有 Docker Compose 的 Caddy 服务中增加:
```yaml
volumes:
- /var/www/duoji:/srv/duoji:ro
```
不要覆盖原有 volumes只追加这一项。容器内的 `/srv/duoji` 对应本项目的静态文件目录。
### 3. 增加 Caddy 站点
将 [`deploy/Caddyfile.duoji`](deploy/Caddyfile.duoji) 的内容追加到现有 Caddyfile。配置核心如下
```caddy
duoji.dbpi.com.cn {
root * /srv/duoji
encode gzip zstd
try_files {path} /index.html
file_server
}
```
修改前先备份 Caddyfile并确认没有同名的 `duoji.dbpi.com.cn` 配置。修改后先验证:
```bash
docker exec galderma-caddy-1 caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
```
由于新增了 bind mount `/var/www/duoji:/srv/duoji:ro`**必须重启 Caddy 容器才会挂载**`caddy reload` 不会重新挂载 volume执行
```bash
cd /root/galderma
docker-compose up -d caddy
```
实际影响约 3 秒,仅重启 Caddygalderma-api / galderma-db 容器不受影响。如果现有容器内的 Caddyfile 路径不同,以 Docker Compose 的实际挂载路径为准。不要为了部署本项目执行整个 Compose 栈的重建或清理操作。
### 4. 验证
```bash
curl -I https://duoji.dbpi.com.cn/
curl -I https://duoji.dbpi.com.cn/catalog-products/precision-gears/418.jpg
curl -I https://duoji.dbpi.com.cn/catalog-products/precision-gears-size/418.jpg
```
浏览器中再检查首页、`#selector``#products``#precision-gears`,并打开任意精密齿轮产品确认"产品尺寸"可以切换。
## 后续更新
首次部署后已经创建了 `duoji-node-modules``duoji-npm-cache` 两个 named volume后续更新直接复用
```bash
git pull --ff-only origin main
docker run --rm \
-v "$PWD":/src \
-v duoji-node-modules:/src/node_modules \
-v duoji-npm-cache:/root/.npm \
-w /src \
-e npm_config_registry=https://registry.npmmirror.com \
node:22-alpine \
sh -lc 'npm ci --no-audit --no-fund && npm run build:static'
sudo rsync -a --delete dist-static/ /var/www/duoji/
```
只更新静态文件时不需要重新构建或清理其他业务容器,也不需要重启 Caddy 容器Caddy 的 `file_server` 每次请求都会读磁盘,新文件一上来就生效)。仅当 `docker-compose.yml` 或 Caddyfile 本身有改动时才需要 `docker-compose up -d caddy`
## 其他部署方式
仓库中的 [`Dockerfile.static`](Dockerfile.static) 和 [`deploy/nginx-static.conf`](deploy/nginx-static.conf) 可用于独立服务器或独立容器场景,但不适用于当前已经由 Caddy 占用 80/443 的服务器。当前服务器优先使用"静态文件 + 现有 Caddy"方案。
## 注意事项
- 静态版的"申请样品"和"联系我们"表单目前只在浏览器中生成演示编号,不会将线索写入 CRM 或数据库。
- 如果后续要保存客户线索,需要另行接入表单 API、企业微信、CRM 或数据库,不要把密钥写进前端代码。
- 页面使用根路径资源,建议部署在域名根路径,不建议直接部署到 `/servo/` 子目录。
- 目前尺寸图仅在产品详情弹窗切换到"产品尺寸"时加载,图片体积主要影响磁盘和用户主动查看尺寸图时的下载,不会首屏一次性加载全部图片。