version: '3.8' services: # MySQL 数据库服务 mysql: image: mysql:8.0 container_name: pregnancy-mysql restart: always ports: # 允许外网访问(生产环境建议配置防火墙白名单) - "3306:3306" environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?Please set MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE:-pregnancy_meal} MYSQL_USER: ${MYSQL_USER:?Please set MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD:?Please set MYSQL_PASSWORD} TZ: Asia/Shanghai volumes: # 数据持久化 - mysql_data:/var/lib/mysql # 初始化脚本 - ./target/classes/db/migration:/docker-entrypoint-initdb.d:ro command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --default-time-zone=+08:00 healthcheck: test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -p\"$$MYSQL_ROOT_PASSWORD\" --silent"] interval: 10s timeout: 5s retries: 5 start_period: 30s networks: - pregnancy-net # Spring Boot 应用服务 app: build: context: . dockerfile: Dockerfile container_name: pregnancy-app restart: always init: true # 不再暴露到宿主机,仅内部网络访问 expose: - "8080" environment: # 数据库连接配置 DB_URL: jdbc:mysql://mysql:3306/${MYSQL_DATABASE:-pregnancy_meal}?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true DB_USERNAME: ${MYSQL_USER:?Please set MYSQL_USER} DB_PASSWORD: ${MYSQL_PASSWORD:?Please set MYSQL_PASSWORD} # 阿里云 AI 配置 ALI_AI_KEY: ${ALI_AI_KEY:?Please set ALI_AI_KEY} # 微信小程序配置 WX_MINIAPP_APPID: ${WX_MINIAPP_APPID:?Please set WX_MINIAPP_APPID} WX_MINIAPP_SECRET: ${WX_MINIAPP_SECRET:?Please set WX_MINIAPP_SECRET} # JWT 配置 JWT_SECRET: ${JWT_SECRET:?Please set JWT_SECRET} JWT_EXPIRATION: ${JWT_EXPIRATION:-604800000} # JVM 参数(可通过环境变量覆盖 Dockerfile 中的默认值) JAVA_OPTS: ${JAVA_OPTS:--XX:MaxRAMPercentage=75.0 -XX:InitialRAMPercentage=75.0 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/logs/heapdump.hprof -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai} volumes: # 日志持久化 - app_logs:/app/logs depends_on: mysql: condition: service_healthy healthcheck: test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost:8080/api/v3/api-docs"] interval: 30s timeout: 10s retries: 3 start_period: 60s networks: - pregnancy-net # Nginx 反向代理服务 nginx: image: nginx:1.25-alpine container_name: pregnancy-nginx restart: always ports: - "80:80" # 如需 HTTPS,取消下面的注释并配置 SSL 证书 # - "443:443" volumes: # Nginx 配置文件 - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro # SSL 证书目录(如需 HTTPS) # - ./nginx/ssl:/etc/nginx/ssl:ro # Nginx 日志 - nginx_logs:/var/log/nginx depends_on: app: condition: service_healthy healthcheck: test: ["CMD-SHELL", "nc -z localhost 80 || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 10s networks: - pregnancy-net # 数据卷定义 volumes: mysql_data: driver: local app_logs: driver: local nginx_logs: driver: local # 网络定义 networks: pregnancy-net: driver: bridge