Skip to Content

快速开始

本地开发

使用 Docker Compose 启动完整环境:

docker compose up -d

服务访问地址:

停止服务

# 停止服务 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 自动构建

推送代码到 maindevelop 分支时,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.sh

详见:GitHub Secrets 配置

Dockerfile 说明

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 #123
  • v1.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" # 左侧是主机端口,可以修改

相关文档