1. 环境准备与基础配置

第一次用Docker Compose部署Ruoyi前后端分离项目时,我踩了不少坑。现在把完整流程整理出来,帮你省去至少80%的调试时间。先来看基础环境搭建:

系统要求:建议使用Ubuntu 20.04 LTS或CentOS 7+,内存至少4GB。我实测在2GB内存的机器上跑MySQL时经常OOM崩溃,特别是数据量大时。

安装Docker和Docker Compose只需三条命令:

# 安装Docker(国内镜像加速版)
curl -fsSL https://get.docker.com | sh
sudo systemctl enable --now docker

# 安装Docker Compose(v2版本)
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

配置国内镜像加速(解决拉取镜像慢的问题):

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ]
}
EOF
sudo systemctl restart docker

目录结构规划很重要,这是我优化后的方案:

ruoyi-docker/
├── docker-compose.yml       # 主配置文件
├── frontend/
│   ├── Dockerfile           # 前端Dockerfile
│   └── dist/                # 前端编译后的静态文件
├── backend/
│   ├── Dockerfile           # 后端Dockerfile
│   └── ruoyi.jar            # 后端打包文件
├── openresty/
│   └── conf/
│       └── nginx.conf       # OpenResty网关配置
├── mysql/
│   ├── data/                # 数据库持久化
│   └── init.sql             # 初始化SQL(可选)
└── redis/
    └── data/                # Redis持久化

提示:用tree -L 3命令可以查看目录树结构,确保你的目录层级正确。我遇到过因为路径错误导致挂载失败的情况,调试了半小时才发现是少了个斜杠。

2. 核心配置文件详解

2.1 Docker Compose编排文件

这是整个项目的核心,我优化后的docker-compose.yml包含这些关键点:

version: '3.8'
services:
  openresty:
    image: openresty/openresty:alpine
    ports: ["9999:80"]
    volumes:
      - ./openresty/conf/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./frontend/dist:/usr/share/nginx/html
    depends_on:
      - backend
    networks: [ruoyi-network]

  backend:
    build: ./backend
    environment:
      SPRING_REDIS_HOST: redis
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/ry?useSSL=false
    ports: ["8888:8888"]
    networks: [ruoyi-network]
    depends_on: 
      mysql: 
        condition: service_healthy
      redis:
        condition: service_healthy

  mysql:
    image: mysql:8.0
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 10s
      retries: 3
    volumes: ["./mysql/data:/var/lib/mysql"]
    environment:
      MYSQL_ROOT_PASSWORD: your_strong_password
      MYSQL_DATABASE: ry
    networks: [ruoyi-network]

  redis:
    image: redis:7-alpine
    command: redis-server --requirepass your_redis_pass
    volumes: ["./redis/data:/data"]
    networks: [ruoyi-network]

networks:
  ruoyi-network:
    driver: bridge

关键优化点

  1. 增加了服务健康检查(healthcheck),确保数据库就绪后再启动后端服务
  2. 使用alpine版本镜像减少体积(OpenResty镜像从200MB降到20MB)
  3. 网络隔离增强安全性,所有服务通过内部网络通信

2.2 OpenResty配置优化

openresty/conf/nginx.conf的配置直接影响性能,这是我的实战优化方案:

worker_processes auto;

events {
    worker_connections 1024;
    use epoll;
    multi_accept on;
}

http {
    # 性能优化参数
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    client_max_body_size 20m;

    # 静态资源缓存
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m inactive=1d;

    server {
        listen 80;
        
        # 前端静态文件
        location / {
            root /usr/share/nginx/html;
            try_files $uri $uri/ /index.html;
            
            # 开启gzip压缩
            gzip on;
            gzip_types text/plain text/css application/json application/javascript;
        }

        # API代理配置
        location /prod-api/ {
            proxy_pass http://backend:8888/;
            proxy_set_header X-Real-IP $remote_addr;
            
            # 连接池优化
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            
            # 超时设置
            proxy_connect_timeout 5s;
            proxy_read_timeout 30s;
        }

        # 静态资源长期缓存
        location ~* \.(js|css|png|jpg)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
}

性能提升技巧

  • 启用epoll事件模型(Linux系统)
  • 配置静态资源缓存减少后端压力
  • 开启HTTP/1.1连接复用
  • 设置合理的超时时间(避免雪崩效应)

3. 构建与部署实战

3.1 前端部署要点

前端项目需要先打包:

npm install
npm run build:prod

关键是要确保vue.config.js中的配置正确:

module.exports = {
  publicPath: process.env.NODE_ENV === 'production' 
    ? '/' 
    : '/',
  devServer: {
    proxy: {
      '/prod-api': {
        target: 'http://localhost:8080',
        changeOrigin: true
      }
    }
  }
}

前端Dockerfile的优化版本:

FROM nginx:alpine

# 设置时区
RUN apk add --no-cache tzdata && \
    cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 复制前端文件
COPY dist/ /usr/share/nginx/html

# 自定义nginx配置(可选)
# COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

3.2 后端特殊处理

后端Dockerfile需要特别注意字体问题(验证码生成需要):

FROM openjdk:8-jdk-alpine

# 安装中文字体和图形库
RUN apk add --no-cache \
    fontconfig \
    ttf-dejavu \
    ttf-wqy-zenhei \
    freetype \
    libxext \
    libxrender

# 创建字体缓存
RUN fc-cache -f -v

COPY ruoyi.jar /app.jar

# JVM参数优化
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"

ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -Djava.awt.headless=true -jar /app.jar"]

常见问题解决

  • 验证码不显示?检查字体安装和headless模式
  • 内存溢出?调整JVM参数(G1垃圾回收器适合内存较大的场景)

3.3 一键启动与验证

启动所有服务:

docker-compose up -d --build

验证服务状态:

#!/bin/bash
echo "=== 服务状态检查 ==="
docker-compose ps

echo -e "\n=== 前端访问测试 ==="
curl -I http://localhost:9999

echo -e "\n=== 后端API测试 ==="
curl -I http://localhost:9999/prod-api/captchaImage

echo -e "\n=== 数据库连接测试 ==="
docker exec ruoyi-mysql mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SHOW DATABASES;"

4. 高级优化技巧

4.1 OpenResty性能调优

  1. 启用Lua JIT编译器
http {
    lua_package_path "/usr/local/openresty/lualib/?.lua;;";
    init_by_lua_block {
        require "resty.core"
    }
}
  1. 动态负载均衡(适用于集群部署):
upstream backend_servers {
    server backend1:8888 weight=5;
    server backend2:8888 weight=3;
    keepalive 32;
}

location /prod-api/ {
    proxy_pass http://backend_servers;
}
  1. 请求限流
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

location /prod-api/ {
    limit_req zone=api_limit burst=20 nodelay;
    # 其他配置...
}

4.2 安全加固方案

  1. 禁用不必要的信息暴露
server {
    server_tokens off;
    more_clear_headers 'Server';
    more_clear_headers 'X-Powered-By';
}
  1. HTTPS配置(使用Let's Encrypt):
server {
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    
    # 强制跳转HTTPS
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
}
  1. Docker安全配置
services:
  mysql:
    security_opt:
      - no-new-privileges:true
    read_only: true  # 容器只读
    tmpfs: /tmp      # 临时目录内存挂载

4.3 监控与日志

  1. 日志收集配置
services:
  backend:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
  1. Prometheus监控
services:
  prometheus:
    image: prom/prometheus
    ports: ["9090:9090"]
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

配套的prometheus.yml配置:

scrape_configs:
  - job_name: 'ruoyi'
    static_configs:
      - targets: ['backend:8888', 'mysql:3306']

5. 常见问题解决方案

问题1:前端访问出现404

  • 检查nginx.conf中的try_files配置
  • 确认前端文件是否成功复制到/usr/share/nginx/html
  • 查看OpenResty容器日志:docker logs ruoyi-openresty

问题2:数据库连接失败

  • 检查MySQL容器是否健康:docker inspect ruoyi-mysql
  • 验证连接字符串格式(特别注意时区参数)
  • 查看初始化SQL是否执行成功

问题3:Redis连接超时

  • 检查密码配置是否一致
  • 确认网络连通性:docker exec ruoyi-backend ping redis
  • 调整Redis的timeout参数

性能问题排查流程

  1. 使用docker stats查看资源占用
  2. 通过arthas诊断Java应用性能
  3. 分析Nginx访问日志:goaccess -f access.log

我在实际部署中发现,80%的性能问题都出在数据库查询和网络延迟上。建议在Spring Boot应用中添加Druid监控:

# application-prod.yml
spring:
  datasource:
    druid:
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*

最后提醒:所有密码建议通过docker-compose --env-file方式传入,不要直接写在配置文件中。完整的项目结构我已经放在Gitee上,需要可以直接克隆使用。

更多推荐