version: '3.8' services: # PostgreSQL 数据库 postgres: image: postgres:15-alpine container_name: photography_postgres environment: POSTGRES_DB: photography POSTGRES_USER: postgres POSTGRES_PASSWORD: ${DB_PASSWORD:-photography_password} POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C" ports: - "${DB_PORT:-5432}:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./migrations:/docker-entrypoint-initdb.d networks: - photography_network restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 30s timeout: 10s retries: 3 # Redis 缓存 redis: image: redis:7-alpine container_name: photography_redis ports: - "${REDIS_PORT:-6379}:6379" volumes: - redis_data:/data networks: - photography_network restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 3 command: redis-server --appendonly yes # 后端 API 服务 backend: build: context: . dockerfile: Dockerfile container_name: photography_backend environment: # 数据库配置 DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-photography_password} DB_NAME: photography DB_SSL_MODE: disable # Redis 配置 REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD: "" REDIS_DB: 0 # JWT 配置 JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production} JWT_EXPIRES_IN: 24h # 服务器配置 PORT: 8080 GIN_MODE: ${GIN_MODE:-release} # 文件上传配置 UPLOAD_TYPE: local UPLOAD_PATH: /app/uploads UPLOAD_BASE_URL: http://localhost:8080/uploads UPLOAD_MAX_SIZE: 10485760 # 10MB # 日志配置 LOG_LEVEL: ${LOG_LEVEL:-info} LOG_FORMAT: json ports: - "${API_PORT:-8080}:8080" volumes: - upload_data:/app/uploads - ./configs:/app/configs:ro networks: - photography_network depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 30s # Nginx 反向代理 (生产环境) nginx: image: nginx:alpine container_name: photography_nginx ports: - "${HTTP_PORT:-80}:80" - "${HTTPS_PORT:-443}:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro - upload_data:/var/www/uploads:ro - ./ssl:/etc/nginx/ssl:ro networks: - photography_network depends_on: - backend restart: unless-stopped healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"] interval: 30s timeout: 10s retries: 3 profiles: - production # 数据卷 volumes: postgres_data: driver: local redis_data: driver: local upload_data: driver: local # 网络 networks: photography_network: driver: bridge