Docker
仓库根构建 Node standalone 镜像,分离公开变量与运行时密钥。
已有服务器或容器宿主时,可用 Docker 构建 Node 应用(apps/web),接入服务后通过 HTTPS 反向代理开放。
开始前准备
准备 Docker、完整仓库源码、独立生产 Postgres、真实邮件与已启用存储/支付凭据,以及域名和 HTTPS 代理。开发 Postgres 配置不等于生产运维方案。构建命令在仓库根目录执行。
构建
docker build -f apps/web/Dockerfile -t musemvp:latest --build-arg NEXT_PUBLIC_SITE_URL=https://app.example.com --build-arg NEXT_PUBLIC_DEFAULT_LOCALE=en .按启用功能追加 NEXT_PUBLIC_GOOGLE_ONE_TAP_CLIENT_ID、NEXT_PUBLIC_TURNSTILE_SITE_KEY、NEXT_PUBLIC_EMAIL_SUPPORT 的 build args。公开变量被 Next 内联,运行时修改不能替代重新构建。
Dockerfile 使用 Node 22、pnpm 与 Turbo prune,最终运行 node apps/web/server.js。镜像不自动执行生产迁移,也不启动 Postgres。
数据库与运行
准备专门的生产环境文件(示例 apps/web/.env.production),按 环境变量 配置真实邮件/认证/支付/存储;MAIL_PROVIDER=console 在生产被拒绝。不要包含 seed 默认账号配置或把密钥作为 build args。
数据库命令默认读取 apps/web/.env.local,执行迁移前检查该文件/注入的连接串确实指向目标数据库:
pnpm db:status
pnpm db:migrate
docker run -d --name musemvp-app --restart unless-stopped --env-file apps/web/.env.production -p 127.0.0.1:3000:3000 musemvp:latest
docker logs musemvp-app应用位于容器内时 DATABASE_URL 的 localhost 指向自身,不是宿主或另一个 Postgres 容器。使用可达主机/Compose 服务名,配置持久卷、TLS、备份和回滚。
上线前验证 HTTPS、OAuth 回调、Cookie、真实邮件、沙盒支付与资产上传,见 发布检查清单。
确认结果
上方回环端口映射适合同机 HTTPS 代理。配置代理转发到该端口;代理也在容器中时改用私有网络。打开 HTTPS 域名,检查启动日志、登录、真实邮件、保存数据和启用的上传/支付。替换应用容器不应丢失独立数据库数据。
生产迁移使用独立发布 checkout:根脚本读取 .env.local,不是运行时 .env.production。安排数据库备份、适用时的持久卷、监控和镜像回滚,不在生产 seed 开发账号。
常见问题
| 问题 | 处理方式 |
|---|---|
| 缺少 workspace 文件 | 根目录用 -f apps/web/Dockerfile 构建 |
| 数据库不可达 | 检查容器网络和数据库主机,不用容器 localhost |
| 公开 URL 仍错误 | 使用正确公开 build args 重建 |
| 代理返回 502 | 查看容器日志、端口映射与代理网络 |