这里采用多阶段构建,先用Maven构建项目,然后将构建好的jar包放到jre运行环境中。

# Dockerfile

# docker/backend/Dockerfile

# Stage 1: Build the application using Maven
# 选择一个包含 Maven 和 JDK 的基础镜像 (根据 RuoYi 要求选择 JDK 版本, 如 8 或 11)
FROM maven:3.8-openjdk-11 AS builder

# 设置工作目录为 /app
WORKDIR /app

# 复制 Maven 包装器和项目定义文件 (利用缓存)
# 注意:这里的 pom.xml 和模块路径是相对于 Dockerfile 的位置调整的
# 我们将在 Docker Compose 中设置 build context 为 RuoYi-Vue 根目录
COPY pom.xml .
COPY ruoyi-common ruoyi-common
COPY ruoyi-framework ruoyi-framework
COPY ruoyi-system ruoyi-system
COPY ruoyi-quartz ruoyi-quartz
COPY ruoyi-generator ruoyi-generator
COPY ruoyi-admin ruoyi-admin
# 如果有其他依赖模块,也需要复制

# 下载依赖 (如果 pom.xml 或模块定义未改变,此层会被缓存)
# 如果只需要构建 ruoyi-admin,可以优化此步骤,但完整构建更简单
RUN mvn dependency:go-offline -B

# 复制所有源代码 (如果源代码改变,从这里开始的层会重新构建)
# (上面已经复制了,这一步是为了确保所有文件都在)
# 可以省略,因为上面已经分模块复制了

# 执行 Maven 打包命令,跳过测试
# -pl ruoyi-admin 指定只打包 ruoyi-admin 模块
# -am 同时构建依赖的模块
RUN mvn clean package -pl ruoyi-admin -am -DskipTests

# Stage 2: Create the runtime image
# 使用一个精简的 JRE 镜像
FROM openjdk:11-jre-slim

WORKDIR /app

# 从构建阶段复制构建好的 Jar 包
# Jar 包通常在模块的 target 目录下
COPY --from=builder /app/ruoyi-admin/target/ruoyi-admin.jar ./app.jar

# 暴露后端服务端口 (默认 8080)
EXPOSE 8080

# 设置容器启动时执行的命令
# 使用 exec 格式,允许传递信号
# 通过环境变量传递数据库和 Redis 配置 (将在 docker-compose 中设置)
ENTRYPOINT ["java", \
            "-Djava.security.egd=file:/dev/./urandom", \
            "-jar", \
            "app.jar", \
            "--spring.datasource.url=jdbc:mysql://${RUOYI_MYSQL_HOST:mysql}:${RUOYI_MYSQL_PORT:3306}/${RUOYI_MYSQL_DB:ry-vue}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai", \
            "--spring.datasource.username=${RUOYI_MYSQL_USER:root}", \
            "--spring.datasource.password=${RUOYI_MYSQL_PASS:password}", \
            "--spring.redis.host=${RUOYI_REDIS_HOST:redis}", \
            "--spring.redis.port=${RUOYI_REDIS_PORT:6379}", \
            "--spring.redis.password=${RUOYI_REDIS_PASS:}" \
           ]
# 注意: 上述配置覆盖了 application.yml 中的值。确保环境变量名与 Docker Compose 中一致。

准备数据初始化脚本

Docker Compose 可以在 MySQL 容器首次启动时自动执行 *.sql*.sh 脚本。

  1. RuoYi-Vue 源码根目录下创建一个 docker/mysql/init 目录。

  2. 将 RuoYi 源码中的 sql/quartz.sqlsql/ry_2023xxxx.sql (选择最新的 ry_*.sql) 复制到 docker/mysql/init/ 目录下。

mkdir -p docker/mysql/init
cp sql/quartz.sql docker/mysql/init/
# 根据你的源码版本选择最新的 ry_*.sql 文件
cp sql/ry_2023xxxx.sql docker/mysql/init/ry_init.sql # 重命名为 ry_init.sql 或保持原名

在根目录下创建docker-compose.yaml文件

# docker-compose.yml
version: '3.8'

services:
  mysql:
    image: mysql:5.7 # 或 8.0, 确保与 RuoYi 兼容
    container_name: ruoyi-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${RUOYI_MYSQL_ROOT_PASS:-password} # 设置 root 密码 (默认 password)
      MYSQL_DATABASE: ${RUOYI_MYSQL_DB:-ry-vue}            # 创建的数据库名 (默认 ry-vue)
      MYSQL_USER: ${RUOYI_MYSQL_USER:-user1}                 # 使用的用户 (生产环境创建独立用户)
      MYSQL_PASSWORD: ${RUOYI_MYSQL_PASS:-password}         # 用户的密码
    ports:
      - "${RUOYI_MYSQL_EXPOSE_PORT:-3306}:3306" # 映射到宿主机端口 (可选)
    volumes:
      - mysql_data:/var/lib/mysql                 # 数据持久化
      - ./docker/mysql/init:/docker-entrypoint-initdb.d # 挂载初始化脚本目录
    networks:
      - ruoyi-net
    restart: unless-stopped
    command: # 设置 MySQL 字符集等
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci

  redis:
    image: redis:6.2 # 选择合适的 Redis 版本
    container_name: ruoyi-redis
    environment:
      # 如果 Redis 需要密码
      # REDIS_PASSWORD: ${RUOYI_REDIS_PASS:-} # 默认无密码
    command: ["redis-server", "--requirepass", "${RUOYI_REDIS_PASS:-}"] # 启动时设置密码 (如果环境变量为空则无密码)
    ports:
      - "${RUOYI_REDIS_EXPOSE_PORT:-6379}:6379" # 映射到宿主机端口 (可选)
    volumes:
      - redis_data:/data # 数据持久化
    networks:
      - ruoyi-net
    restart: unless-stopped

  ruoyi-backend:
    container_name: ruoyi-backend
    build:
      context: . # 构建上下文是当前目录 (RuoYi-Vue 根目录)
      dockerfile: docker/backend/Dockerfile # 指定 Dockerfile 路径
    environment:
      # 这些环境变量会传递给后端 Dockerfile 的 ENTRYPOINT
      RUOYI_MYSQL_HOST: mysql # 使用服务名作为 Host
      RUOYI_MYSQL_PORT: 3306
      RUOYI_MYSQL_DB: ${RUOYI_MYSQL_DB:-ry-vue}
      RUOYI_MYSQL_USER: ${RUOYI_MYSQL_USER:-root}
      RUOYI_MYSQL_PASS: ${RUOYI_MYSQL_PASS:-password}
      RUOYI_REDIS_HOST: redis # 使用服务名作为 Host
      RUOYI_REDIS_PORT: 6379
      RUOYI_REDIS_PASS: ${RUOYI_REDIS_PASS:-}
      # 可以添加其他 Spring Boot 配置覆盖, 如 SERVER_PORT
      # SERVER_PORT: 8080
    ports:
      - "${RUOYI_BACKEND_EXPOSE_PORT:-8080}:8080" # 映射后端端口
    depends_on: # 确保数据库和 Redis 先启动 (但不保证完全可用)
      - mysql
      - redis
    networks:
      - ruoyi-net
    restart: unless-stopped

  ruoyi-frontend:
    container_name: ruoyi-frontend
    build:
      context: . # 构建上下文是当前目录
      dockerfile: docker/frontend/Dockerfile # 指定 Dockerfile 路径
    ports:
      - "${RUOYI_FRONTEND_EXPOSE_PORT:-80}:80" # 映射前端 Nginx 端口到宿主机 80
    depends_on:
      - ruoyi-backend # 依赖后端服务 (确保后端服务名在 Nginx 配置中正确)
    networks:
      - ruoyi-net
    restart: unless-stopped

networks:
  ruoyi-net: # 定义网络
    driver: bridge

volumes: # 定义数据卷
  mysql_data:
  redis_data: