# ═══════════════════════════════════════════════════════════════ # docker-compose.yml — 模式一:新建 MySQL(全栈部署) # # 用法: # cp .env.docker.example .env.docker # # 编辑 .env.docker 修改密码和 SECRET_KEY # docker compose --env-file .env.docker up -d # # 包含服务: # db — MySQL 8.0 # app — Flask + Gunicorn # nginx — Nginx 反向代理(可选,使用 --profile nginx 启用) # ═══════════════════════════════════════════════════════════════ services: # ── MySQL 数据库 ──────────────────────────────────────────── db: image: mysql:8.0 container_name: resource_library_db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE:-resource_library} MYSQL_USER: ${MYSQL_USER:-resource_library} MYSQL_PASSWORD: ${MYSQL_PASSWORD} volumes: - mysql_data:/var/lib/mysql - ./docker/mysql-init:/docker-entrypoint-initdb.d:ro # 可放自定义初始化 SQL command: > --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password --innodb-buffer-pool-size=256M ports: - "${MYSQL_EXPOSE_PORT:-127.0.0.1:3306}:3306" # 默认仅本机可访问 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "${MYSQL_USER:-resource_library}", "-p${MYSQL_PASSWORD}"] interval: 10s timeout: 5s retries: 10 start_period: 30s networks: - backend # ── Flask 应用 ────────────────────────────────────────────── app: build: context: . dockerfile: Dockerfile container_name: resource_library_app restart: unless-stopped depends_on: db: condition: service_healthy environment: FLASK_ENV: ${FLASK_ENV:-production} SECRET_KEY: ${SECRET_KEY} DATABASE_URL: mysql+pymysql://${MYSQL_USER:-resource_library}:${MYSQL_PASSWORD}@db:3306/${MYSQL_DATABASE:-resource_library} ADMIN_USERNAME: ${ADMIN_USERNAME:-admin} ADMIN_PASSWORD: ${ADMIN_PASSWORD:-Admin@123456} ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@example.com} GUNICORN_WORKERS: ${GUNICORN_WORKERS:-4} GUNICORN_TIMEOUT: ${GUNICORN_TIMEOUT:-120} MAX_UPLOAD_SIZE_MB: ${MAX_UPLOAD_SIZE_MB:-500} LOG_LEVEL: ${LOG_LEVEL:-info} volumes: - uploads_data:/app/app/static/uploads ports: - "${APP_PORT:-5000}:5000" # 使用 Nginx 时可去掉此行 networks: - backend - frontend logging: driver: json-file options: max-size: "20m" max-file: "5" # ── Nginx 反向代理(可选,加 --profile nginx 启用)────────── nginx: image: nginx:1.27-alpine container_name: resource_library_nginx restart: unless-stopped profiles: ["nginx"] depends_on: - app ports: - "${NGINX_HTTP_PORT:-80}:80" - "${NGINX_HTTPS_PORT:-443}:443" volumes: - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro - uploads_data:/app/app/static/uploads:ro # 让 Nginx 直接服务静态文件 # - ./docker/ssl:/etc/nginx/ssl:ro # HTTPS 证书目录(取消注释后使用) networks: - frontend logging: driver: json-file options: max-size: "10m" max-file: "3" # ── 持久化卷 ──────────────────────────────────────────────────── volumes: mysql_data: name: resource_library_mysql uploads_data: name: resource_library_uploads # ── 网络 ──────────────────────────────────────────────────────── networks: backend: name: resource_library_backend internal: true # db 不暴露给外部网络 frontend: name: resource_library_frontend