250d4355b9
P5-prep Task 1(docs/plans/2026-09-21-P5-准备件.md): - docker/server.Dockerfile:单镜像 photo-live-server 多角色(api-cn/api-ov/ worker/sync/migrate-deploy/seed-admin,entrypoint.sh 分发;migrate-deploy 支持 cn|ov|all 区域参数)。三阶段:全量 install(锁文件冻结)→ prisma generate 双库 + 逐包构建;--prod 依赖层;runtime=node:20-alpine+openssl/curl + 全局 prisma@5.22.0(对齐锁文件)+ 双库 client 镜像内重建(db-cn 落 pnpm store .prisma、db-ov 落包内 generated/)。sharp 走 musl 预编译验证通过。 - docker/web.Dockerfile + infra/deploy/nginx.conf.template:photo-live-web (nginx:alpine + envsubst 模板)。viewer(/,history 回退) + admin(/admin/, hash 路由) + /v1 反代 API_UPSTREAM(含 /v1/realtime WS 升级)+ /assets/、/admin/assets/、/embed/v1/ immutable 长缓存(admin assets 的 alias 前缀剥除坑已实测修复)。VITE_* 为构建期参数(VIEWER_BASE/ EMBED_ORIGIN 随域名构建传入)。 - infra/deploy/docker-compose.cn.yml / -ov.yml:cn=api-cn+worker+sync+web, ov=api-ov+web-ov(核实架构:sync 仅 cn 侧,inbox/emergency 内嵌 api-ov, 无 ov 侧 sync 进程);健康检查 /v1/health、unless-stopped、json-file 10m×3、外部 1panel-network 复用 1Panel MySQL/Redis、SERVER_IMAGE/ WEB_IMAGE 环境变量化镜像 tag(回滚杠杆)。 - .env.production.example-cn/-ov:生产变量全量清单(cn 25 键/ov 24 键, DB/Redis/OSS/SYNC/AUTH/限速/域名分组注释,源自 services+packages process.env 全量审计);.gitignore 放行 example,真实 .env.production-* 永不入库。 - infra/deploy/README-1Panel.md:镜像导入双路径(save tar 导入 / 仓库 pull)、 MySQL 建库授权 SQL(utf8mb4_0900_bin,<8.0.30 回退 utf8mb4_bin——D12)、 Redis 连接、1Panel 编排、OpenResty 反代+证书、migrate-deploy 一次性容器、 首次部署顺序(DB→迁移→ov 栈→cn 栈→seed→冒烟)。 - 根 package.json pnpm.onlyBuiltDependencies 增补 sharp/prisma/@prisma/ engines/@prisma/client(镜像构建所需 install 脚本白名单)。 本地验证:两镜像构建成功(server 988MB / web 97.7MB);compose config 校验 通过;server 镜像内逐服务 require(sharp/argon2/双 Prisma client/bullmq/ ioredis)与双引擎 so.node、migrate-deploy 角色、无 .env 泄漏均实测;web 镜像 容器实测路由(viewer 回退/admin 子路径/assets 与 embed immutable/WS 代理路径 502 语义)全通过。未起真实栈(无真实 DB,符合准备件边界)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
79 lines
3.2 KiB
Plaintext
79 lines
3.2 KiB
Plaintext
# infra/deploy/nginx.conf.template —— photo-live-web nginx 配置模板。
|
||
# 官方 nginx 镜像启动脚本对 /etc/nginx/templates/*.template 执行 envsubst 并
|
||
# 输出到 /etc/nginx/conf.d/。模板变量仅 ${API_UPSTREAM}(compose environment
|
||
# 注入);envsubst 只替换已定义的环境变量,$uri/$host 等 nginx 变量不受影响。
|
||
#
|
||
# 路由布局(viewer history 路由 / admin hash 路由,路由模式核实自
|
||
# apps/viewer/src/router/index.ts createWebHistory 与 apps/admin/src/router/
|
||
# index.ts createWebHashHistory):
|
||
# / viewer SPA(try_files 回退 index.html)
|
||
# /admin/ admin 静态(hash 路由无需 history 回退;try_files 仅兜底)
|
||
# /assets/ viewer vite 内容寻址产物 → immutable 一年
|
||
# /admin/assets/ admin vite 内容寻址产物 → immutable 一年
|
||
# /embed/v1/ 嵌入 loader.js(版本目录即内容版本)→ immutable 一年;
|
||
# /embed/:slotToken 是 viewer SPA 路由,走 / 的回退,不被本条误捕
|
||
# /v1/ 反代 API_UPSTREAM(HTTP + WS /v1/realtime 升级透传)
|
||
|
||
map $http_upgrade $connection_upgrade {
|
||
default upgrade;
|
||
'' close;
|
||
}
|
||
|
||
server {
|
||
listen 80;
|
||
server_name _;
|
||
|
||
root /usr/share/nginx/html/viewer;
|
||
index index.html;
|
||
|
||
gzip on;
|
||
gzip_comp_level 5;
|
||
gzip_min_length 1024;
|
||
gzip_types text/css application/javascript application/json image/svg+xml;
|
||
|
||
# /v1 → API 容器(viewer/admin 前端均为同源相对路径请求)。
|
||
location /v1/ {
|
||
proxy_pass ${API_UPSTREAM};
|
||
proxy_http_version 1.1;
|
||
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;
|
||
# WS(/v1/realtime)升级;普通 HTTP 请求不受影响。
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection $connection_upgrade;
|
||
proxy_read_timeout 75s;
|
||
proxy_send_timeout 75s;
|
||
}
|
||
|
||
# admin(hash 路由:静态直达即工作;try_files 兜底异常直链)。
|
||
location ^~ /admin/ {
|
||
alias /usr/share/nginx/html/admin/;
|
||
try_files $uri $uri/ /admin/index.html;
|
||
}
|
||
# admin 内容寻址资源:immutable(注意 alias 指到 assets/ 本身:location 前缀
|
||
# /admin/assets/ 被剥去后拼到 alias 末尾,多剥一段就 404——实测坑位)。
|
||
location ^~ /admin/assets/ {
|
||
alias /usr/share/nginx/html/admin/assets/;
|
||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||
try_files $uri =404;
|
||
}
|
||
|
||
# 嵌入 loader(版本化路径 /embed/v1/loader.js,apps/viewer/public 静态携带)。
|
||
location ^~ /embed/v1/ {
|
||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||
try_files $uri =404;
|
||
}
|
||
|
||
# viewer 内容寻址资源:immutable。
|
||
location ^~ /assets/ {
|
||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||
try_files $uri =404;
|
||
}
|
||
|
||
# viewer SPA history 路由回退。
|
||
location / {
|
||
try_files $uri $uri/ /index.html;
|
||
}
|
||
}
|