version: '3.8' services: # MySQL数据库 mysql: image: school-news-mysql:latest container_name: school-news-mysql restart: always environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-123456} MYSQL_DATABASE: ${MYSQL_DATABASE:-school_news} MYSQL_USER: ${MYSQL_USER:-schoolnews} MYSQL_PASSWORD: ${MYSQL_PASSWORD:-123456} TZ: Asia/Shanghai ports: - "${MYSQL_PORT:-3306}:3306" volumes: # 数据持久化(命名卷) - mysql-data:/var/lib/mysql # 自定义配置文件(可选,取消注释以启用) # 如需自定义MySQL配置,取消下面的注释并修改mysql/my.cnf # - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --default-authentication-plugin=mysql_native_password - --max_connections=1000 - --max_allowed_packet=64M networks: - school-news-network healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p${MYSQL_ROOT_PASSWORD:-123456}"] interval: 10s timeout: 5s retries: 5 start_period: 30s # Redis缓存 redis: image: redis:7-alpine container_name: school-news-redis restart: always environment: TZ: Asia/Shanghai ports: - "${REDIS_PORT:-6379}:6379" volumes: # 数据持久化(命名卷) - redis-data:/data # Redis配置文件(命名卷) - redis-config:/usr/local/etc/redis command: redis-server /usr/local/etc/redis/redis.conf --requirepass ${REDIS_PASSWORD:-123456} networks: - school-news-network healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 10s timeout: 3s retries: 5 # 后端服务 school-news-serv: image: school-news-serv:latest container_name: school-news-serv restart: always depends_on: mysql: condition: service_healthy redis: condition: service_healthy environment: # 数据库配置 MYSQL_HOST: mysql MYSQL_PORT: 3306 MYSQL_DATABASE: ${MYSQL_DATABASE:-school_news} MYSQL_USER: ${MYSQL_USER:-root} MYSQL_PASSWORD: ${MYSQL_PASSWORD:-123456} # Redis配置 REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-123456} # JVM配置 JAVA_OPTS: "-Xms512m -Xmx1g -XX:+UseG1GC" TZ: Asia/Shanghai ports: - "${SERV_PORT:-8081}:8081" volumes: # 配置文件(命名卷) - serv-config:/app/config # 日志目录(命名卷) - serv-logs:/app/logs # 上传文件目录(命名卷) - serv-uploads:/app/uploads # 爬虫脚本目录(默认不挂载,保留在镜像内) # 注意:挂载会覆盖镜像内容,如需运行时更新爬虫脚本可取消注释 - serv-crawler:/app/crawler networks: - school-news-network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8081/schoolNewsServ/actuator/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s # 前端服务(Node + Vite Preview) school-news-web: image: school-news-web:latest container_name: school-news-web restart: always depends_on: - school-news-serv environment: TZ: Asia/Shanghai NODE_ENV: production # 不直接暴露端口,通过nginx反向代理访问 expose: - "4173" volumes: # 运行时配置文件(命名卷) - web-config:/app/config # 日志目录(命名卷) - web-logs:/app/logs networks: - school-news-network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:4173/"] interval: 30s timeout: 10s retries: 3 start_period: 20s # Nginx反向代理 nginx: image: nginx:alpine # 直接使用官方镜像,无需自定义构建 container_name: school-news-nginx restart: always depends_on: - school-news-web - school-news-serv environment: TZ: Asia/Shanghai ports: - "${NGINX_PORT:-80}:80" volumes: # Nginx配置文件(命名卷) - nginx-config:/etc/nginx:ro # 日志目录(命名卷) - nginx-logs:/var/log/nginx networks: - school-news-network healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"] interval: 30s timeout: 10s retries: 3 start_period: 10s networks: school-news-network: driver: bridge # 命名卷定义(数据存储在当前目录下的volumes/子目录) # 使用前请先运行初始化脚本:./init-volumes.sh 或 init-volumes.bat volumes: # ===== MySQL ===== mysql-data: driver: local driver_opts: type: none o: bind device: ./volumes/mysql/data # ===== Redis ===== redis-data: driver: local driver_opts: type: none o: bind device: ./volumes/redis/data redis-config: driver: local driver_opts: type: none o: bind device: ./volumes/redis/config # ===== 后端服务 ===== serv-config: driver: local driver_opts: type: none o: bind device: ./volumes/serv/config serv-logs: driver: local driver_opts: type: none o: bind device: ./volumes/serv/logs serv-uploads: driver: local driver_opts: type: none o: bind device: ./volumes/serv/uploads # 爬虫脚本目录(可选,默认不启用) # 注意:启用后会覆盖镜像内的爬虫脚本,需先复制镜像内容到volumes/serv/crawler serv-crawler: driver: local driver_opts: type: none o: bind device: ./volumes/serv/crawler # ===== 前端服务 ===== web-config: driver: local driver_opts: type: none o: bind device: ./volumes/web/config web-logs: driver: local driver_opts: type: none o: bind device: ./volumes/web/logs # ===== Nginx ===== nginx-config: driver: local driver_opts: type: none o: bind device: ./volumes/nginx/config nginx-logs: driver: local driver_opts: type: none o: bind device: ./volumes/nginx/logs