部署指南
Mono monorepo 在 Zeabur、Docker 和生产数据库上的部署方式
Mono 是一个 pnpm workspace + Turborepo monorepo。生产部署时推荐显式使用 Dockerfile,而不是依赖平台的默认 monorepo 自动识别。
推荐策略
当前仓库推荐的生产部署方式:
- Zeabur + Dockerfile:每个 app 一个独立服务,平台直接构建指定 Dockerfile
- 根目录构建,按 app 裁剪:通过
turbo prune --docker只保留目标应用和必要 workspace 依赖 - 运行时环境变量分离:每个服务单独维护环境变量,不在仓库里硬编码生产密钥
为什么不用默认的 Node.js Monorepo 自动识别
Zeabur 的 monorepo 自动识别可以帮助发现应用,但它不能替代显式 Docker 部署:
ZBPACK_APP_DIR只能告诉 Zeabur 把哪个目录当成 Node.js 项目- 它不会自动帮你选择正确的 Dockerfile
- 直接在整个 monorepo 上执行
pnpm install会安装完整 workspace,构建比实际需要更重 turbo prune --docker可以把镜像构建范围收缩到单个 app 及其真实依赖
仓库中的 Dockerfile 约定
根目录使用 Dockerfile.[service] 命名:
Dockerfile.mono-web:部署apps/mono-webDockerfile.timemark:部署apps/timemark
每个 Dockerfile 都遵循同一套路:
- 在仓库根目录执行
turbo prune --docker - 只安装裁剪后 workspace 的依赖
- 构建 Next.js standalone 输出
- 使用更小的运行时镜像启动服务
Zeabur 部署 mono-web
1. 创建服务
在 Zeabur 中为 mono-web 单独创建一个服务:
- 新建项目或进入现有项目
- 连接 GitHub 仓库
01mvp/mono - 保持工作目录为仓库根目录
- 启用 Dockerfile 部署
2. 配置服务变量
最关键的变量是:
ZBPACK_DOCKERFILE_NAME=mono-web如果之前为了平台自动识别设置过 ZBPACK_APP_DIR,在切到 Dockerfile 部署后通常可以移除;保留为 / 也不会影响构建,但没有必要继续依赖它。
3. 配置运行时环境变量
至少需要补齐应用运行依赖的环境变量,常见示例:
DATABASE_URL=postgresql://...
BETTER_AUTH_SECRET=...
BETTER_AUTH_URL=https://your-domain.com
NEXT_PUBLIC_SITE_URL=https://your-domain.com
S3_ENDPOINT=...
S3_REGION=...
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...
S3_BUCKET=...
NEXT_PUBLIC_S3_ENDPOINT=...
OPENAI_API_KEY=...
OPENAI_BASE_URL=...
OPENAI_MODEL=...具体必填项以 配置说明 为准。
4. 触发部署
推送到绑定分支后,Zeabur 会在仓库根目录找到 Dockerfile.mono-web 并开始构建。
推荐检查点:
- 构建日志中是否出现
turbo prune --docker - Next.js 是否以 standalone 方式输出
- 运行阶段是否成功读取
DATABASE_URL和鉴权变量
Zeabur 如何匹配 Dockerfile
Zeabur 支持以下根目录命名模式:
Dockerfile[service].DockerfileDockerfile.[service]
本仓库采用 Dockerfile.[service],因此:
ZBPACK_DOCKERFILE_NAME=mono-web对应Dockerfile.mono-webZBPACK_DOCKERFILE_NAME=timemark对应Dockerfile.timemark
即使 Zeabur 服务名和后缀相同,仍建议显式设置 ZBPACK_DOCKERFILE_NAME,避免后续重命名服务时引入隐式耦合。
多应用部署
同一个 monorepo 可以在 Zeabur 中部署多个服务,但每个服务都应该独立配置:
| 服务 | Dockerfile 变量 | 说明 |
|---|---|---|
mono-web | ZBPACK_DOCKERFILE_NAME=mono-web | 主站和文档站 |
timemark | ZBPACK_DOCKERFILE_NAME=timemark | Timemark 应用 |
每个服务共享同一个 Git 仓库,但拥有各自的域名、环境变量和部署历史。
Docker 本地与生产部署
本地验证
cp apps/mono-web/.env.example apps/mono-web/.env.local
docker compose up -d
docker compose logs -f手动构建镜像
docker build -f Dockerfile.mono-web -t mono-web .
docker run -d \
--env-file apps/mono-web/.env.production \
-p 3000:3000 \
mono-web环境变量文件
| 文件 | 用途 | 说明 |
|---|---|---|
apps/mono-web/.env.local | 本地开发 | 不提交到 Git |
apps/mono-web/.env.production | 生产运行 | 仅在部署平台或安全环境中使用 |
数据库与迁移
生产数据库推荐:
- Zeabur PostgreSQL:与部署平台集成,一键创建
- Neon:Serverless PostgreSQL,适合低成本起步
数据库变更请使用迁移,不要直接在生产库上做临时变更:
pnpm db:migrate如果 Prisma schema 有变化,部署前先确认已经执行并提交了对应 migration。
域名和可观测性
域名
在 Zeabur 服务设置中绑定自定义域名,并在 DNS 提供商侧配置对应记录。
数据分析
项目使用 Umami 进行访问统计。
当前公开统计看板:
部署检查清单
- Zeabur 服务工作目录保持在仓库根目录
- 已设置
ZBPACK_DOCKERFILE_NAME=mono-web - 运行时环境变量已补齐
- 数据库 migration 已提交并可执行
- 自定义域名和
NEXT_PUBLIC_SITE_URL保持一致 - 构建日志确认使用了裁剪后的 workspace