代码部署
Docker 部署
使用 Docker 容器部署 Better SaaS,实现一致且可扩展的部署方案
Docker 部署
使用 Docker 容器部署 Better SaaS,实现一致、可扩展且便携的跨环境部署。
前置要求
- Docker Engine 20.10+
 - Docker Compose 2.0+
 - 2GB+ 可用内存
 - 基础 Docker 知识
 
Docker 快速开始
1. 克隆和设置
git clone https://github.com/your-org/better-saas.git
cd better-saas
cp env.example .env2. 配置环境变量
编辑 .env 文件:
# 数据库
DATABASE_URL=postgresql://postgres:password@db:5432/bettersaas
# 认证
BETTER_AUTH_SECRET=your-super-secret-key-here
BETTER_AUTH_URL=http://localhost:3000
# GitHub OAuth
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
# Google OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
# Stripe
STRIPE_SECRET_KEY=sk_test_your-stripe-secret-key
STRIPE_PUBLISHABLE_KEY=pk_test_your-stripe-publishable-key
STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secret
# 文件存储 (Cloudflare R2)
CLOUDFLARE_R2_ACCESS_KEY_ID=your-access-key
CLOUDFLARE_R2_SECRET_ACCESS_KEY=your-secret-key
CLOUDFLARE_R2_BUCKET_NAME=your-bucket-name
CLOUDFLARE_R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com3. 构建和运行
# 构建并启动所有服务
docker-compose up -d
# 查看日志
docker-compose logs -f
# 停止服务
docker-compose downDocker Compose 配置
创建 docker-compose.yml:
version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:password@db:5432/bettersaas
    depends_on:
      - db
      - redis
    volumes:
      - ./uploads:/app/uploads
    restart: unless-stopped
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: bettersaas
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    restart: unless-stopped
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: unless-stopped
volumes:
  postgres_data:
  redis_data:Dockerfile 配置
创建优化的 Dockerfile:
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
# 安装 pnpm
RUN npm install -g pnpm
# 复制包文件
COPY package.json pnpm-lock.yaml ./
COPY packages/ ./packages/
# 安装依赖
RUN pnpm install --frozen-lockfile
# 复制源代码
COPY . .
# 构建应用
RUN pnpm build
# 生产阶段
FROM node:18-alpine AS runner
WORKDIR /app
# 安装 pnpm
RUN npm install -g pnpm
# 创建非 root 用户
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# 复制构建的应用
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
# 设置正确的权限
RUN chown -R nextjs:nodejs /app
USER nextjs
EXPOSE 3000
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"
CMD ["node", "server.js"]多阶段构建优化
开发环境 Dockerfile
FROM node:18-alpine
WORKDIR /app
RUN npm install -g pnpm
COPY package.json pnpm-lock.yaml ./
RUN pnpm install
COPY . .
EXPOSE 3000
CMD ["pnpm", "dev"]生产环境 Dockerfile
FROM node:18-alpine AS deps
WORKDIR /app
RUN npm install -g pnpm
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --prod --frozen-lockfile
FROM node:18-alpine AS builder
WORKDIR /app
RUN npm install -g pnpm
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
FROM node:18-alpine AS runner
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
RUN chown -R nextjs:nodejs /app
USER nextjs
EXPOSE 3000
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"
CMD ["node", "server.js"]环境特定配置
开发环境
# docker-compose.dev.yml
version: '3.8'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
    volumes:
      - .:/app
      - /app/node_modules
    depends_on:
      - db
      - redis
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: bettersaas_dev
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"
    volumes:
      - postgres_dev_data:/var/lib/postgresql/data
volumes:
  postgres_dev_data:生产环境
# docker-compose.prod.yml
version: '3.8'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
    restart: unless-stopped
    depends_on:
      - db
      - redis
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: bettersaas
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    restart: unless-stopped
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - app
    restart: unless-stopped
volumes:
  postgres_data:
  redis_data:数据库迁移
在 Docker 中运行迁移
# 运行数据库迁移
docker-compose exec app pnpm db:migrate
# 填充数据
docker-compose exec app pnpm db:seed
# 重置数据库
docker-compose exec app pnpm db:reset迁移脚本
创建 scripts/docker-migrate.sh:
#!/bin/bash
# 等待数据库准备就绪
until docker-compose exec db pg_isready -U postgres; do
  echo "等待数据库..."
  sleep 2
done
# 运行迁移
docker-compose exec app pnpm db:migrate
# 填充初始数据
docker-compose exec app pnpm db:seed
echo "数据库迁移完成!"健康检查
应用健康检查
# 添加到 Dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/api/health || exit 1Docker Compose 健康检查
services:
  app:
    # ... 其他配置
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
  db:
    # ... 其他配置
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 30s
      timeout: 10s
      retries: 3监控和日志
集中式日志
# 添加到 docker-compose.yml
services:
  app:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"使用 Prometheus 监控
# docker-compose.monitoring.yml
version: '3.8'
services:
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
  grafana:
    image: grafana/grafana
    ports:
      - "3001:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
volumes:
  prometheus_data:
  grafana_data:安全最佳实践
1. 非 Root 用户
# 创建和使用非 root 用户
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
USER nextjs2. 安全扫描
# 扫描漏洞
docker scout cves better-saas:latest
# 使用安全扫描器
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image better-saas:latest3. 密钥管理
# 使用 Docker secrets
services:
  app:
    secrets:
      - db_password
      - stripe_secret
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password
      - STRIPE_SECRET_KEY_FILE=/run/secrets/stripe_secret
secrets:
  db_password:
    file: ./secrets/db_password.txt
  stripe_secret:
    file: ./secrets/stripe_secret.txt性能优化
1. 多阶段构建
使用多阶段构建减少镜像大小:
# 分别构建依赖
FROM node:18-alpine AS deps
# ... 安装生产依赖
FROM node:18-alpine AS builder  
# ... 构建应用
FROM node:18-alpine AS runner
# ... 复制构建的应用2. 层缓存
# 首先复制包文件以获得更好的缓存
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
# 在依赖之后复制源代码
COPY . .
RUN pnpm build3. 资源限制
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '1'
          memory: 1G故障排除
常见问题
- 
端口已被占用
# 检查端口使用情况 lsof -i :3000 # 终止进程 kill -9 <PID> - 
数据库连接问题
# 检查数据库日志 docker-compose logs db # 测试连接 docker-compose exec db psql -U postgres -d bettersaas - 
构建失败
# 清理构建缓存 docker system prune -a # 无缓存重新构建 docker-compose build --no-cache 
调试模式
# 使用调试输出运行
DEBUG=* docker-compose up
# 访问容器 shell
docker-compose exec app sh
# 查看容器日志
docker-compose logs -f app部署命令
# 开发环境
docker-compose -f docker-compose.dev.yml up -d
# 生产环境
docker-compose -f docker-compose.prod.yml up -d
# 包含监控
docker-compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d
# 扩展服务
docker-compose up -d --scale app=3