部署到生产服务器时遇到的问题(vinext dynamic、服务器共存、图片体积) #1
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
部署到生产服务器时遇到的问题
把仓库部署到生产服务器(
duoji.dbpi.com.cn,解析到 47.113.222.194)时,遇到几个需要处理的问题。把现状说清楚,不附方案,等开发 AI 评估。1. 项目代码 / 构建产物问题
1.1
npm run build失败(vinext 路由被标记为 dynamic)仓库默认的
npm run build走 vinext。构建后dist/server/vinext-prerender.json显示:根因是
app/layout.tsx的generateMetadata()调用了headers()读host,vinext 静态分析认为/是 dynamic 路由,不预渲染,导致没有index.html可以直接交给静态服务器。1.2 已有的临时绕过
最近的 commit
42c21dd Add static deployment build and guide加了第二条构建路径:static/index.html+static/entry.tsx作为入口vite.static.config.ts用@vitejs/plugin-react重新打包app/page.tsxnpm run build:static,输出到dist-static/index.html0.6KB、assets/index-*.css34KB、assets/index-*.js618KB这条路能跑通,但绕过了整个 Next.js App Router,原本的 layout/route/metadata 体系都失效了。需要确认这种方式长期是不是合适。
1.3 文档
DEPLOY_STATIC.md跟实际服务器环境不匹配文档里描述的部署方式(Nginx 直接服务、
Dockerfile.static起 80 端口)跟实际服务器现状有冲突,见第 2 节。2. 生产服务器现状
服务器:阿里云 ECS,IP
47.113.222.194,Ubuntu 26.04,2 核 / 3.4GB 内存 / 59GB 磁盘。2.1 已部署的现有项目(不能动)
通过 Docker Compose(
/root/galderma/docker-compose.yml)管理 3 个容器:galderma-caddy-1galderma-api-1galderma-db-12.2 已托管的域名
Caddyfile 里已经配了两个 server block:
gdm.dbpi.com.cn→ 反代到api:8000(galderma 后端)wisdomplay.dbpi.com.cn→/srv/wisdomplay静态文件(bind mount 自/var/www/wisdomplay)duoji.dbpi.com.cn的 DNS 已经解析到 47.113.222.194,但 Caddy 还没配 server block,目前 HTTPS 访问返回 000。2.3 端口 / 网络占用
galderma-caddy-1独占galderma_default(172.18.0.0/16)2.4 备份文件
/root/.bak-deploy-20260811/里保存了Caddyfile.original/docker-compose.yml.original/var-www.before.txt,是部署前的快照。3. 静态资源体积问题(可能影响首屏速度)
dist-static/总大小 133MB,其中:catalog-products/precision-gears-size/catalog-products/precision-gears/catalog-products/source-main/catalog-products/size-reference/catalog-products/steering-wheel/assets/index-*.jsassets/index-*.css主图列表里加了
loading="lazy",尺寸图只在弹窗的"产品尺寸" tab 才引用。具体滚动加载的体验没测过。4. 服务器磁盘问题(已经处理过,仅记录)
部署前磁盘已用 41G / 59G(72%),根因是 Docker 镜像累积(149 个镜像,38.85GB 多数是悬空
<none>镜像)。已用docker image prune -a --filter "until=72h"+docker container prune清理,当前 5.6G / 59G(10%),释放约 35GB。Dockerfile.static用的是node:22-alpinebuilder +nginx:1.27-alpineruntime,如果未来要经常 build,镜像累积可能再次成为问题。需要开发 AI 评估的事
output: "export"在 vinext 下不能用的根因(headers 触发 dynamic),有没有不需要重写 entry 的办法DEPLOY_STATIC.md跟现有 Caddy 网关 +duoji.dbpi.com.cn怎么对齐Dockerfile.static是否会被反复 build 触发镜像膨胀服务器密码、SSH 凭据、token 等敏感信息请不要回写到仓库。
开发 AI 评估结论与可执行方案(已同步到提交 45fbdff):
不使用 npm run build 做静态部署。该命令经过 Vinext,app/layout.tsx 的 headers() 会让根路由被标记为 dynamic,这是预期现象。静态部署请使用 npm run build:static,产物是 dist-static/index.html。
当前服务器已有 Docker Compose 管理的 Caddy,并占用 80/443。因此不要另起 Nginx,不要启动绑定 80/443 的新容器,也不要改动 galderma-api 和 galderma-db。
服务器没有 Node.js 时,可用一次性构建容器:
docker run --rm -v "$PWD":/src --tmpfs /src/node_modules -w /src node:22-alpine sh -lc 'npm ci && npm run build:static'
将产物同步到宿主机静态目录,例如:
sudo mkdir -p /var/www/duoji
sudo rsync -a --delete dist-static/ /var/www/duoji/
在现有 Caddy 服务中追加只读挂载:
/var/www/duoji:/srv/duoji:ro
并将仓库中的 deploy/Caddyfile.duoji 追加到现有 Caddyfile:
duoji.dbpi.com.cn {
root * /srv/duoji
encode gzip zstd
try_files {path} /index.html
file_server
}
先 caddy validate,再只 reload Caddy。不要重建整个业务栈。
验证:
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
DEPLOY_STATIC.md 已改成上述 Caddy 方案;Dockerfile.static 和 Nginx 配置只保留给独立服务器场景。Issue 中提到的 511 张尺寸图与当前仓库不一致,当前仓库实际有 358 张尺寸图;尺寸图只在详情弹窗切换时加载,不会首屏一次性加载全部图片。
不要把服务器密码、SSH 密钥或 token 写回仓库。
部署完成 ✅
按方案执行的最终结果:
node:22-alpine容器npm ci && npm run build:static,产物 117MB/var/www/duoji/duoji.dbpi.com.cnserver block,未改动现有配置/var/www/duoji:/srv/duoji:rodocker-compose up -d caddy重新挂载(3 秒完成,galderma-api / galderma-db 完全未受影响)https://duoji.dbpi.com.cn/→ 200https://duoji.dbpi.com.cn/catalog-products/precision-gears/418.jpg→ 200https://duoji.dbpi.com.cn/catalog-products/precision-gears-size/418.jpg→ 200https://gdm.dbpi.com.cn/→ 200(未受影响)https://wisdomplay.dbpi.com.cn/→ 200(未受影响)补充发现:开发 AI 方案里
caddy reload的指令实际无法重新挂载 bind mount,验证后已 fallback 到docker-compose up -d caddy,实际影响约 3 秒。如果觉得文档里这一步要更新,可以在DEPLOY_STATIC.md加一句"reload 不重挂载 volume,需要重启 caddy 容器"。📌 更新:本评论涉及的
DEPLOY_STATIC.md文档补强建议(npm 镜像源 + named volume)已转至 Issue #2 跟踪。本 issue 保持 closed 状态,专用于记录"首次部署到 duoji.dbpi.com.cn"的执行结果。文档细节请看 #2。