anxin-ruoyi/docker/docker-compose.production.yml
2026-01-08 20:47:24 +08:00

290 lines
7.8 KiB
YAML

# Docker Compose生产环境配置文件
# 若依框架前后端分离Docker部署方案 - 生产环境
# Requirements: 5.3, 6.5
version: '3.8'
services:
# Redis缓存服务 - 生产环境配置
anxin-redis:
image: redis:7.2-alpine
container_name: anxin-redis-prod
restart: always
environment:
TZ: Asia/Shanghai
ports:
- "127.0.0.1:${REDIS_PORT_EXPORT:-6379}:6379" # 生产环境仅绑定本地接口
volumes:
- redis-data-prod:/data
- redis-logs-prod:/var/log/redis
networks:
- anxin-prod-network
deploy:
resources:
limits:
memory: ${REDIS_MEMORY_LIMIT:-256M}
cpus: '${REDIS_CPU_LIMIT:-0.5}'
reservations:
memory: 128M
cpus: '0.25'
healthcheck:
test: ["CMD", "redis-cli", "ping"]
timeout: 10s
retries: 5
interval: 30s
start_period: 30s
command: redis-server --appendonly yes --maxmemory 200mb --maxmemory-policy allkeys-lru --requirepass ${REDIS_PASSWORD:-}
logging:
driver: "json-file"
options:
max-size: "${LOG_MAX_SIZE:-200m}"
max-file: "${LOG_MAX_FILES:-15}"
security_opt:
- no-new-privileges:true
# MySQL数据库服务 - 生产环境配置
anxin-mysql:
image: mysql:8.0.36
container_name: anxin-mysql-prod
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME:-anxin_prod}
MYSQL_USER: ${DB_USER:-anxin_prod}
MYSQL_PASSWORD: ${DB_PASSWORD}
TZ: Asia/Shanghai
ports:
- "${DB_PORT:-3306}:3306" # 允许外部访问,使用环境变量指定的端口
volumes:
- mysql-data-prod:/var/lib/mysql
- ./database/init:/docker-entrypoint-initdb.d:ro
- ./configs/my.cnf.prod:/etc/mysql/conf.d/my.cnf:ro
- mysql-logs-prod:/var/log/mysql
networks:
- anxin-prod-network
deploy:
resources:
limits:
memory: ${DATABASE_MEMORY_LIMIT:-1024M}
cpus: '${DATABASE_CPU_LIMIT:-1.0}'
reservations:
memory: 512M
cpus: '0.5'
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
timeout: 20s
retries: 10
interval: 30s
start_period: 60s
logging:
driver: "json-file"
options:
max-size: "${LOG_MAX_SIZE:-200m}"
max-file: "${LOG_MAX_FILES:-15}"
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
- /var/run/mysqld
# Spring Boot后端服务 - 生产环境配置
anxin-backend:
build:
context: ../
dockerfile: docker/backend/Dockerfile
target: production
image: anxin-backend:prod
container_name: anxin-backend-prod
restart: always
environment:
# 数据库连接配置 - 使用与启动脚本一致的环境变量名
DB_HOST: anxin-mysql
DB_PORT: 3306
DB_NAME: ${DB_NAME:-anxin_prod}
DB_USER: ${DB_USER:-anxin_prod}
DB_PASSWORD: ${DB_PASSWORD}
# Redis配置
REDIS_HOST: ${REDIS_HOST:-anxin-redis}
REDIS_PORT: ${REDIS_PORT:-6379}
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
REDIS_DATABASE: ${REDIS_DATABASE:-0}
# Spring Boot配置
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
SERVER_PORT: 8080
# JVM配置
JAVA_OPTS: ${JAVA_OPTS:--Xms1024m -Xmx2048m -Djava.security.egd=file:/dev/./urandom -XX:+UseG1GC -XX:+UseStringDeduplication}
# 日志配置
LOG_LEVEL: ${LOG_LEVEL:-WARN}
LOG_PATH: /app/logs
LOG_MAX_SIZE: ${LOG_MAX_SIZE:-200MB}
LOG_MAX_FILES: ${LOG_MAX_FILES:-15}
# 文件上传路径
UPLOAD_PATH: /app/uploadPath
# 系统配置
TZ: Asia/Shanghai
# 生产环境特有配置
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,metrics
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: never
LOGGING_LEVEL_COM_RUOYI: WARN
LOGGING_LEVEL_ROOT: WARN
# 安全配置
SPRING_SECURITY_REQUIRE_SSL: true
SERVER_SSL_ENABLED: false # 通过反向代理处理SSL
ports:
- "127.0.0.1:${BACKEND_PORT:-8080}:8080" # 生产环境仅绑定本地接口
volumes:
- backend-logs-prod:/app/logs
- backend-uploads-prod:/app/uploadPath
- ./configs:/app/config:ro
networks:
- anxin-prod-network
depends_on:
anxin-mysql:
condition: service_healthy
anxin-redis:
condition: service_healthy
deploy:
resources:
limits:
memory: ${BACKEND_MEMORY_LIMIT:-2048M}
cpus: '${BACKEND_CPU_LIMIT:-2.0}'
reservations:
memory: 1024M
cpus: '1.0'
replicas: ${BACKEND_REPLICAS:-1}
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8080/actuator/health || exit 1"]
timeout: 30s
retries: 5
interval: 30s
start_period: 120s
logging:
driver: "json-file"
options:
max-size: "${LOG_MAX_SIZE:-200m}"
max-file: "${LOG_MAX_FILES:-15}"
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
# Vue3前端服务 - 生产环境配置
anxin-frontend:
build:
context: ../
dockerfile: docker/frontend/Dockerfile
target: production
args:
API_BASE_URL: ${API_BASE_URL:-http://localhost:8080}
NODE_ENV: production
image: anxin-frontend:prod
container_name: anxin-frontend-prod
restart: always
environment:
TZ: Asia/Shanghai
NODE_ENV: production
ports:
- "${FRONTEND_PORT:-80}:80"
volumes:
- frontend-logs-prod:/var/log/nginx
- ./configs/nginx.conf.prod:/etc/nginx/conf.d/default.conf:ro
networks:
- anxin-prod-network
depends_on:
anxin-backend:
condition: service_healthy
deploy:
resources:
limits:
memory: ${FRONTEND_MEMORY_LIMIT:-512M}
cpus: '${FRONTEND_CPU_LIMIT:-1.0}'
reservations:
memory: 256M
cpus: '0.5'
replicas: ${FRONTEND_REPLICAS:-1}
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]
timeout: 10s
retries: 3
interval: 30s
start_period: 30s
logging:
driver: "json-file"
options:
max-size: "${LOG_MAX_SIZE:-200m}"
max-file: "${LOG_MAX_FILES:-15}"
security_opt:
- no-new-privileges:true
# 网络配置 - 生产环境
networks:
anxin-prod-network:
name: ${NETWORK_NAME:-anxin-prod-network}
driver: bridge
ipam:
driver: default
config:
- subnet: ${SUBNET:-172.23.0.0/16}
gateway: ${GATEWAY:-172.23.0.1}
driver_opts:
com.docker.network.bridge.name: anxin-prod-br0
# 卷配置 - 生产环境
volumes:
# Redis数据持久化卷
redis-data-prod:
driver: local
driver_opts:
type: none
o: bind
device: ${REDIS_DATA_PATH:-./data/production/redis}
# Redis日志卷
redis-logs-prod:
driver: local
driver_opts:
type: none
o: bind
device: ${REDIS_LOG_PATH:-./log/production/redis}
# 数据库数据持久化卷
mysql-data-prod:
driver: local
driver_opts:
type: none
o: bind
device: ${MYSQL_DATA_PATH:-./data/mysql}
# 数据库日志卷
mysql-logs-prod:
driver: local
driver_opts:
type: none
o: bind
device: ${MYSQL_LOG_PATH:-./log/mysql}
# 后端应用日志卷
backend-logs-prod:
driver: local
driver_opts:
type: none
o: bind
device: ${BACKEND_LOG_PATH:-./log/backend}
# 后端文件上传卷
backend-uploads-prod:
driver: local
driver_opts:
type: none
o: bind
device: ${BACKEND_UPLOAD_PATH:-./data/uploads}
# 前端Nginx日志卷
frontend-logs-prod:
driver: local
driver_opts:
type: none
o: bind
device: ${FRONTEND_LOG_PATH:-./log/nginx}