Files
ai-app-database/docker-compose.yml
huty 3ad430e3e3 feat: 添加 Docker 容器化部署支持
支持两种部署模式,兼容新建 MySQL 和现有 MySQL:

- Dockerfile:Python 3.12-slim 两阶段构建,非 root 运行
- docker-compose.yml:全栈模式(含 MySQL 8.0 + 可选 Nginx)
- docker-compose.external-db.yml:接入现有 MySQL 模式
- docker/entrypoint.sh:自动等待 DB 就绪 → 初始化表 → 启动 Gunicorn
- docker/nginx.conf:反向代理 + 静态文件直出 + 安全响应头
- .env.docker.example / .env.external-db.example:各模式配置示例
- .gitattributes:确保 entrypoint.sh 在 Windows 上保持 LF 换行

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 00:38:14 +09:00

119 lines
4.4 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ═══════════════════════════════════════════════════════════════
# 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