version: '3.8' services: # PostgreSQL 数据库 postgres: image: postgres:16-alpine container_name: miaosi-postgres environment: POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} POSTGRES_DB: ${POSTGRES_DB:-miaosi} volumes: - ./data/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 # Redis 缓存/消息队列 redis: image: redis:7-alpine container_name: miaosi-redis volumes: - ./data/redis:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 5 # FastAPI 后端服务 api: build: context: . dockerfile: Dockerfile container_name: miaosi-api environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-miaosi} REDIS_URL: redis://redis:6379/0 env_file: - .env depends_on: postgres: condition: service_healthy redis: condition: service_healthy volumes: - video_temp:/tmp/videos # Celery Worker celery-worker: build: context: . dockerfile: Dockerfile container_name: miaosi-celery-worker environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-miaosi} REDIS_URL: redis://redis:6379/0 env_file: - .env depends_on: postgres: condition: service_healthy redis: condition: service_healthy volumes: - video_temp:/tmp/videos command: celery -A app.celery_app worker -l info -Q default,review -c 2 # Celery Beat (定时任务调度器) celery-beat: build: context: . dockerfile: Dockerfile container_name: miaosi-celery-beat environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-miaosi} REDIS_URL: redis://redis:6379/0 env_file: - .env depends_on: redis: condition: service_healthy celery-worker: {} command: celery -A app.celery_app beat -l info # Next.js 前端 frontend: build: context: ../frontend dockerfile: Dockerfile args: NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL:-https://your-domain.com} NEXT_PUBLIC_USE_MOCK: "false" container_name: miaosi-frontend depends_on: - api # Nginx 反向代理 nginx: image: nginx:alpine container_name: miaosi-nginx ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro - /etc/letsencrypt:/etc/letsencrypt:ro depends_on: - api - frontend volumes: video_temp: