快速开始
本地开发
使用 Docker Compose 启动完整环境:
docker compose up -d服务访问地址:
- Admin: http://localhost:3000
- API: http://localhost:3001
- Doc: http://localhost:3003
- PostgreSQL: localhost:5433
停止服务
# 停止服务
docker compose down
# 清理所有数据
docker compose down -v镜像构建
本地构建
本项目包含三个 Docker 镜像:
# 构建 API (NestJS)
docker build -f apps/api/Dockerfile -t procure-api .
# 构建 Admin (Next.js)
docker build -f apps/admin/Dockerfile -t procure-admin .
# 构建 Doc (Next.js + Nextra)
docker build -f apps/doc/Dockerfile -t procure-doc .CI/CD 自动构建
推送代码到 main 或 develop 分支时,GitHub Actions 自动构建并推送镜像。
配置 Registry 秘钥:
# 1. 创建配置文件
cp .env.secrets.example .env.secrets
# 2. 编辑秘钥(添加 Docker Registry 配置)
# DOCKER_REGISTRY=docker.io
# DOCKER_USERNAME=your-username
# DOCKER_PASSWORD=your-token
# 3. 推送到 GitHub
./scripts/setup-secrets.shDockerfile 说明
API (NestJS)
# apps/api/Dockerfile
FROM node:22-alpine AS deps
# 安装依赖...
FROM node:22-alpine AS builder
# 构建应用...
FROM node:22-alpine AS runner
# 运行应用
USER nestjs
EXPOSE 3001
CMD ["node", "dist/apps/api/src/main"]特点:
- 多阶段构建,最小化镜像大小 (~350MB)
- 非 root 用户运行
- 包含 Prisma Client 生成
- 使用 dumb-init 处理信号
Admin (Next.js)
# apps/admin/Dockerfile
FROM node:22-alpine AS deps
# 安装依赖...
FROM node:22-alpine AS builder
# 构建应用...
FROM node:22-alpine AS runner
# 运行应用
USER nextjs
EXPOSE 3000
CMD ["node", "apps/admin/server.js"]特点:
- Standalone 输出模式(需要
output: "standalone") - 自包含,无需 node_modules (~500MB)
- 复制 .next/standalone, .next/static, public
Doc (Next.js + Nextra)
# apps/doc/Dockerfile
FROM node:24-alpine AS deps
# 安装依赖...
FROM node:24-alpine AS builder
# 构建应用...
FROM node:24-alpine AS runner
# 运行应用
USER nextjs
EXPOSE 3000
CMD ["node", "apps/doc/server.js"]特点:
- 基于 Nextra 的文档站点
- Standalone 输出模式
- 包含完整的 API 参考文档
Docker Compose
配置文件
# docker-compose.yml
services:
postgres:
image: postgres:17-alpine
ports:
- "5433:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: procure
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
api:
build:
context: .
dockerfile: apps/api/Dockerfile
ports:
- "3001:3001"
environment:
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/procure
JWT_SECRET: ${JWT_SECRET:-dev-secret}
depends_on:
postgres:
condition: service_healthy
web:
build:
context: .
dockerfile: apps/admin/Dockerfile
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/procure
JWT_SECRET: ${JWT_SECRET:-dev-secret}
depends_on:
- api
doc:
build:
context: .
dockerfile: apps/doc/Dockerfile
ports:
- "3003:3000"
volumes:
postgres_data:环境变量
创建 .env 文件:
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/procure
JWT_SECRET=your-secret-key
SESSION_SECRET=your-session-secret生产部署
使用预构建镜像
# docker-compose.prod.yml
services:
api:
image: ghcr.io/{owner}/procure/api:latest
environment:
DATABASE_URL: ${DATABASE_URL}
JWT_SECRET: ${JWT_SECRET}
web:
image: ghcr.io/{owner}/procure/web:latest
environment:
DATABASE_URL: ${DATABASE_URL}
JWT_SECRET: ${JWT_SECRET}
doc:
image: ghcr.io/{owner}/procure/doc:latest启动:
docker compose -f docker-compose.prod.yml up -d从 Registry 拉取
# GitHub Container Registry
docker pull ghcr.io/{owner}/procure/api:latest
docker pull ghcr.io/{owner}/procure/web:latest
docker pull ghcr.io/{owner}/procure/doc:latest
# Docker Hub (需配置 CI)
docker pull docker.io/{username}/procure/api:latest镜像标签
CI 自动生成多种标签:
latest- 最新的 main 分支构建develop- develop 分支main- main 分支pr-123- Pull Request #123v1.0.0- 语义化版本v1.0- 主次版本main-abc1234- 分支名 + commit SHA
故障排除
构建失败
# 清理构建缓存
docker builder prune -a
# 重新构建
docker compose build --no-cache容器无法启动
# 查看日志
docker compose logs api
docker compose logs web
# 检查健康状态
docker compose ps数据库连接失败
# 检查 PostgreSQL 是否就绪
docker compose exec postgres pg_isready -U postgres
# 检查网络
docker compose exec api ping postgres端口冲突
如果端口被占用,修改 docker-compose.yml 中的端口映射:
ports:
- "3100:3000" # 左侧是主机端口,可以修改