一台机器两个项目时,不要让任何一个去占 80 端口
结论:一台云主机上,80 和 443 只属于宿主机 Nginx。各项目只在 127.0.0.1 提供服务,用子路径区分。Docker 里不要再映射 80:80。Node 用 pm2 时必须 fork,cluster 会丢掉 --env-file,线上就像没配密钥。
我把历史决策镜和六度推演放在同一台阿里云上。前者是 Docker(Next.js + FastAPI),后者是静态 dist + pm2。最早 History 自己带了一个 nginx 容器占着 80,根路径就是它。要上第二个项目、根路径还要留给主页时,必须把这个容器删掉。
改完的结构是:浏览器只打 https://www.shuerguo.cn;网关文件在 /etc/nginx/conf.d/gateway.conf;/history 反代到 127.0.0.1:3000,/history/api/ 到 8000;/six-degrees/ 读磁盘上的 dist,API 反代到 3001。
六度踩过一个具体的坑:ecosystem 里写了 interpreter_args: --env-file=.env,但 pm2 默认成 cluster 后,进程命令行只剩下 node server.mjs,环境变量全空。health 返回 hasKey: false,模型名退回代码默认值。改成 exec_mode: fork,删掉旧进程再 start,密钥才进得去。API 同时只监听 127.0.0.1,公网 3001 不再暴露。
Next.js 挂在子路径时,basePath 必须是 UTF-8 的配置文件,多阶段 Docker 的 runner 还要 COPY next.config.mjs,否则运行时 basePath 会丢。这些都不是框架文档第一页会强调的,所以写在这里。