You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

11 KiB

部署架构

文档版本:v1.0
最后更新:2025-01-27


目录

  1. Docker 容器化
  2. Docker Compose 配置
  3. 生产环境部署
  4. 环境配置

Docker 容器化

Dockerfile

# Dockerfile
FROM python:3.11-slim

WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    ffmpeg \
    libpq-dev \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# 安装 Python 依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码
COPY . .

# 创建非 root 用户
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser

# 暴露端口
EXPOSE 8000

# 运行应用
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

.dockerignore

__pycache__
*.pyc
*.pyo
*.pyd
.Python
env/
venv/
.venv
pip-log.txt
pip-delete-this-directory.txt
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.log
.git
.gitignore
.mypy_cache
.pytest_cache
.hypothesis
*.db
*.sqlite3
.env
.env.local
.DS_Store

Docker Compose 配置

docker-compose.yml

version: "3.8"

services:
  # API 服务
  api:
    build: .
    container_name: jointo-api
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/jointo
      - REDIS_URL=redis://redis:6379/0
      - CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672//
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
      - MINIO_ENDPOINT=minio:9000
      - MINIO_ACCESS_KEY=minioadmin
      - MINIO_SECRET_KEY=minioadmin
    depends_on:
      - db
      - redis
      - rabbitmq
      - minio
    volumes:
      - ./app:/app/app
    networks:
      - jointo-network

  # Celery Worker - AI 任务
  celery-worker-ai:
    build: .
    container_name: jointo-celery-ai
    command: celery -A app.tasks.celery_app worker -Q ai --loglevel=info
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/jointo
      - REDIS_URL=redis://redis:6379/0
      - CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672//
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
    depends_on:
      - db
      - redis
      - rabbitmq
    networks:
      - jointo-network

  # Celery Worker - 导出任务
  celery-worker-export:
    build: .
    container_name: jointo-celery-export
    command: celery -A app.tasks.celery_app worker -Q export --loglevel=info
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/jointo
      - REDIS_URL=redis://redis:6379/0
      - CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672//
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
    depends_on:
      - db
      - redis
      - rabbitmq
    networks:
      - jointo-network

  # Celery Beat(定时任务)
  celery-beat:
    build: .
    container_name: jointo-celery-beat
    command: celery -A app.tasks.celery_app beat --loglevel=info
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/jointo
      - REDIS_URL=redis://redis:6379/0
      - CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672//
    depends_on:
      - db
      - redis
      - rabbitmq
    networks:
      - jointo-network

  # PostgreSQL
  db:
    image: postgres:14
    container_name: jointo-db
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=jointo
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    networks:
      - jointo-network

  # Redis
  redis:
    image: redis:7-alpine
    container_name: jointo-redis
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"
    networks:
      - jointo-network

  # RabbitMQ
  rabbitmq:
    image: rabbitmq:3.12-management
    container_name: jointo-rabbitmq
    environment:
      - RABBITMQ_DEFAULT_USER=guest
      - RABBITMQ_DEFAULT_PASS=guest
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq
    ports:
      - "5672:5672"
      - "15672:15672" # 管理界面
    networks:
      - jointo-network

  # MinIO(对象存储)
  minio:
    image: minio/minio
    container_name: jointo-minio
    command: server /data --console-address ":9001"
    environment:
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=minioadmin
    volumes:
      - minio_data:/data
    ports:
      - "9000:9000"
      - "9001:9001" # 管理界面
    networks:
      - jointo-network

  # Nginx(可选)
  nginx:
    image: nginx:alpine
    container_name: jointo-nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - api
    networks:
      - jointo-network

volumes:
  postgres_data:
  redis_data:
  rabbitmq_data:
  minio_data:

networks:
  jointo-network:
    driver: bridge

启动服务

# 启动所有服务
docker-compose up -d

# 查看日志
docker-compose logs -f

# 停止服务
docker-compose down

# 重启服务
docker-compose restart

# 查看服务状态
docker-compose ps

生产环境部署

推荐架构

┌─────────────────────────────────────────────────────────────┐
│                        负载均衡器                            │
│                    (Nginx / AWS ALB)                         │
└───────────────────────────┬─────────────────────────────────┘
                            │
        ┌───────────────────┼───────────────────┐
        │                   │                   │
┌───────▼────────┐  ┌───────▼────────┐  ┌───────▼────────┐
│   API 服务 1   │  │   API 服务 2   │  │   API 服务 3   │
│   (容器)       │  │   (容器)       │  │   (容器)       │
└────────────────┘  └────────────────┘  └────────────────┘
        │                   │                   │
        └───────────────────┼───────────────────┘
                            │
        ┌───────────────────┼───────────────────┐
        │                   │                   │
┌───────▼────────┐  ┌───────▼────────┐  ┌───────▼────────┐
│  PostgreSQL    │  │     Redis      │  │   RabbitMQ     │
│  (主从复制)    │  │   (Cluster)    │  │   (Cluster)    │
└────────────────┘  └────────────────┘  └────────────────┘
        │
┌───────▼────────┐
│   AWS S3 /     │
│   阿里云 OSS   │
└────────────────┘

部署步骤

1. 准备服务器

# 安装 Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# 安装 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

2. 配置环境变量

# 创建 .env 文件
cp .env.example .env

# 编辑环境变量
vim .env

3. 初始化数据库

# 运行数据库迁移
docker-compose exec api alembic upgrade head

# 创建初始数据
docker-compose exec api python scripts/seed_data.py

4. 配置 Nginx

# nginx.conf
upstream api_backend {
    server api:8000;
}

server {
    listen 80;
    server_name api.jointo.ai;

    location / {
        proxy_pass http://api_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # WebSocket 支持
    location /ws {
        proxy_pass http://api_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

5. 配置 SSL(使用 Let's Encrypt)

# 安装 Certbot
sudo apt-get install certbot python3-certbot-nginx

# 获取证书
sudo certbot --nginx -d api.jointo.ai

# 自动续期
sudo certbot renew --dry-run

环境配置

.env.example

# 应用配置
APP_NAME=Jointo
APP_ENV=production
DEBUG=false
SECRET_KEY=your-secret-key-here

# 数据库配置
DATABASE_URL=postgresql://user:password@localhost:5432/jointo

# Redis 配置
REDIS_URL=redis://localhost:6379/0

# Celery 配置
CELERY_BROKER_URL=amqp://guest:guest@localhost:5672//
CELERY_RESULT_BACKEND=redis://localhost:6379/0

# MinIO / S3 配置
MINIO_ENDPOINT=localhost:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_BUCKET_NAME=jointo
MINIO_SECURE=false

# 或使用 AWS S3
# AWS_ACCESS_KEY_ID=your-access-key
# AWS_SECRET_ACCESS_KEY=your-secret-key
# AWS_S3_BUCKET=jointo
# AWS_REGION=us-east-1

# AI 服务配置
OPENAI_API_KEY=your-openai-api-key
STABLE_DIFFUSION_API_KEY=your-sd-api-key
RUNWAY_API_KEY=your-runway-api-key

# JWT 配置
JWT_SECRET_KEY=your-jwt-secret-key
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7

# CORS 配置
CORS_ORIGINS=http://localhost:3000,https://www.jointo.ai

# 日志配置
LOG_LEVEL=INFO
LOG_FILE=logs/app.log

监控和日志

日志收集

# app/core/logging.py
from loguru import logger
import sys

# 配置日志
logger.remove()
logger.add(
    sys.stdout,
    format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
    level="INFO"
)
logger.add(
    "logs/app.log",
    rotation="500 MB",
    retention="10 days",
    compression="zip",
    level="INFO"
)

健康检查

# app/api/v1/health.py
from fastapi import APIRouter
from app.core.database import engine
from app.core.cache import redis_client

router = APIRouter()

@router.get("/health")
async def health_check():
    """健康检查"""
    # 检查数据库
    try:
        engine.connect()
        db_status = "ok"
    except Exception:
        db_status = "error"

    # 检查 Redis
    try:
        redis_client.ping()
        redis_status = "ok"
    except Exception:
        redis_status = "error"

    return {
        "status": "ok" if db_status == "ok" and redis_status == "ok" else "error",
        "database": db_status,
        "redis": redis_status
    }

相关文档


文档版本:v1.0
最后更新:2025-01-27