Docker部署若依管理系统项目
本文详细介绍了若依(RuoYi)权限管理系统的Docker化部署方案。主要内容包括:1) 后端SpringBoot应用的Dockerfile构建,采用Maven多阶段构建优化镜像;2) 前端Vue项目通过Nginx容器部署,配置接口代理;3) 使用Docker Compose编排MySQL、Redis等依赖服务;4) 扩展部署Prometheus+Grafana监控体系,包含节点、容器、Redis
引言
- 若依管理系统简介(基于Spring Boot的权限管理系统)
- Docker在现代化部署中的优势(环境一致性、快速部署、资源隔离
准备工作
- 环境要求:Docker及Docker Compose已安装
获取若依项目源码(GitHub或Gitee仓库)
git clone https://github.com/yangzongzhuan/RuoYi-Vue.git
后端Docker化
- 编写Dockerfile:基于OpenJDK镜像构建Spring Boot应用
FROM maven:3.8-jdk-8 AS build
WORKDIR /app
# 注入阿里云镜像加速
RUN mkdir -p /root/.m2 && \
echo '<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"><mirrors><mirror><id>aliyun</id><name>aliyun</name><url>https://maven.aliyun.com/repository/public</url><mirrorOf>*</mirrorOf></mirror></mirrors></settings>' > /root/.m2/settings.xml
COPY . .
RUN mvn clean package -DskipTests
FROM eclipse-temurin:17-jre-alpine
RUN apk add --update --no-cache ttf-dejavu fontconfig
WORKDIR /app
COPY --from=build /app/ruoyi-admin/target/ruoyi-admin.jar app.jar
ENTRYPOINT ["java", "-Xmx512m", "-jar", "app.jar"]
前端Docker化
- 构建Vue项目静态资源(npm run build)
# 阶段 1: 编译前端
FROM node:16-alpine AS build-stage
WORKDIR /app
# 设置淘宝镜像源,加速 npm install
RUN npm config set registry https://registry.npmmirror.com
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build:prod
# 阶段 2: 运行前端 (Nginx)
FROM nginx:alpine
COPY --from=build-stage /app/dist /usr/share/nginx/html
# 拷贝我们自定义的 nginx.conf
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
配置nginx
vim nginx.conf
worker_processes 1;
events { worker_connections 1024; }
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
# 核心:转发所有接口请求到后端容器
location /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://ruoyi-server:8080/;
}
}
}
编写docker-compose.yml
version: '3'
services:
ruoyi-db:
image: mysql:8.0
container_name: ruoyi-db
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=ry-vue
volumes:
- ./docker-data/db:/var/lib/mysql
- ./sql:/docker-entrypoint-initdb.d # 源码里的sql文件夹
ports:
- "3306:3306"
ruoyi-redis:
image: redis:latest
container_name: ruoyi-redis
ruoyi-server:
build: .
container_name: ruoyi-server
depends_on:
- ruoyi-db
- ruoyi-redis
environment:
- SPRING_DATASOURCE_DRUID_MASTER_URL=jdbc:mysql://ruoyi-db:3306/ry-vue?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
- SPRING_REDIS_HOST=ruoyi-redis
ruoyi-nginx:
build: ./ruoyi-ui
container_name: ruoyi-nginx
volumes:
- /root/java/RuoYi-Vue/ruoyi-ui/nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
depends_on:
- ruoyi-server
启动服务
docker-compose up -d ruoyi-db ruoyi-redis
docker-compose up -d --build ruoyi-server
docker-compose up -d --build ruoyi-nginx
访问ip

部署监控
version: '3'
services:
ruoyi-db:
image: mysql:8.0
container_name: ruoyi-db
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=ry-vue
volumes:
- ./docker-data/db:/var/lib/mysql
- ./sql:/docker-entrypoint-initdb.d # 源码里的sql文件夹
ports:
- "3306:3306"
networks:
- ruoyi-net
ruoyi-redis:
image: redis:latest
container_name: ruoyi-redis
command: redis-server --appendonly yes
volumes:
- ./docker-data/redis:/data
networks:
- ruoyi-net
ruoyi-server:
build: .
container_name: ruoyi-server
depends_on:
- ruoyi-db
- ruoyi-redis
environment:
- SPRING_DATASOURCE_DRUID_MASTER_URL=jdbc:mysql://ruoyi-db:3306/ry-vue?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
- SPRING_REDIS_HOST=ruoyi-redis
networks:
- ruoyi-net
ruoyi-nginx:
build: ./ruoyi-ui
container_name: ruoyi-nginx
volumes:
- /root/java/RuoYi-Vue/ruoyi-ui/nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
networks:
- ruoyi-net
depends_on:
- ruoyi-server
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
# 核心:共享宿主机网络和 PID 以实现“破墙”监控
network_mode: "host"
pid: "host"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
# 容器性能采集 (cAdvisor)
cadvisor:
image: google/cadvisor:latest
container_name: cadvisor
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
networks:
- ruoyi-net
redis-exporter:
image: oliver006/redis_exporter:latest
container_name: redis-exporter
environment:
- REDIS_ADDR=redis://ruoyi-redis:6379
networks:
- ruoyi-net
# 1. Nginx 深度监控采集器
nginx-exporter:
image: nginx/nginx-prometheus-exporter:latest
container_name: nginx-exporter
command:
- "-nginx.scrape-uri=http://ruoyi-nginx/nginx_status"
ports:
- "9113:9113"
depends_on:
- ruoyi-nginx
networks:
- ruoyi-net
# 2. MySQL 深度监控采集器
mysql-exporter:
image: prom/mysqld-exporter:latest
container_name: mysql-exporter
volumes:
- ./my-exporter.cnf:/.my.cnf:ro # 确保这里对应日志里报错的路径
networks:
- ruoyi-net
depends_on:
- ruoyi-db
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
networks:
- ruoyi-net
ports:
- "9090:9090"
# 可视化仪表盘
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
networks:
- ruoyi-net
depends_on:
- prometheus
networks:
ruoyi-net:
driver: bridge
查看docker网段
docker network inspect ruoyi-vue_ruoyi-net
"Name": "ruoyi-vue_ruoyi-net",
"Id": "4a9cee137815fe158841a81a8595fa20bf40c61baee69db672efb40d492ba6a1",
"Created": "2026-02-02T16:07:59.471440835+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
将这里的Gateway写入Prometheus的node-exporter配置中
创建Prometheus的配置文件
mkdir promethues
vim promethues/promethues.yml
global:
scrape_interval: 15s # 默认每 15 秒抓取一次数据
evaluation_interval: 15s
scrape_configs:
# 监控宿主机性能 (CPU, 内存, 磁盘)
- job_name: 'node-exporter'
static_configs:
- targets: ['172.19.0.1:9100'] # 对应的网关信息
# 监控每个容器的资源占用 (cAdvisor)
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
# 监控 Redis 运行状态
- job_name: 'redis-exporter'
static_configs:
- targets: ['redis-exporter:9121']
- job_name: 'nginx-exporter'
static_configs:
- targets: ['nginx-exporter:9113']
- job_name: 'mysql-exporter'
static_configs:
- targets: ['mysql-exporter:9104']
修改nginx配置
vim ruoyi-ui/nginx.conf
worker_processes 1;
events { worker_connections 1024; }
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
# 允许 ruoyi-net 网段访问,或者简单点先允许所有
allow all;
}
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
# 核心:转发所有接口请求到后端容器
location /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://ruoyi-server:8080/;
}
}
}
创建一个mysql配置文件
vim my-exporter.cnf
[client]
user=root
password=password
host=ruoyi-db
然后启动
docker-compose up -d

服务正常启动

配置grafana
这里就不多说了,跟我上个文章差不多

这里直接填服务名就行

数据库主从配置
修改主库(ruoyi-db)配置
主库必须开启二进制日志(binlog)并设置唯一的 server-id。
在宿主机创建或修改主库配置文件(例如 ./mysql/master.cnf):
[mysqld]
server-id=1
log-bin=mysql-bin
# 允许从库连接的网段,也可以不设置
binlog-do-db=ry-vue
然后在 docker-compose.yml 中将该文件挂载到 ruoyi-db
ruoyi-db:
# ... 原有配置 ...
volumes:
- ./mysql/master.cnf:/etc/mysql/conf.d/master.cnf:ro
- ./docker-data/db:/var/lib/mysql
导出主库数据并获取同步位点
锁定主库并备份:
# 进入主库执行
docker exec -it ruoyi-db mysql -uroot -ppassword
在 MySQL 命令行内执行
FLUSH TABLES WITH READ LOCK; -- 锁定只读
SHOW MASTER STATUS; -- 记录下 File 和 Position 的值

导出数据: 打开另一个终端窗口执行
docker exec ruoyi-db mysqldump -uroot -ppassword --all-databases > master_backup.sql
解锁主库: 回到刚才的 MySQL 命令行执行:
UNLOCK TABLES;
配置并添加从库(ruoyi-db-slave)
准备从库配置 ./mysql/slave.cnf
[mysqld]
server-id=2
relay-log=mysql-relay-bin
read-only=1
更新 docker-compose.yml
ruoyi-db-slave:
image: mysql:8.0
container_name: ruoyi-db-slave
environment:
- MYSQL_ROOT_PASSWORD=password
volumes:
- ./mysql/slave.cnf:/etc/mysql/conf.d/slave.cnf:ro
- ./docker-data/db-slave:/var/lib/mysql
- ./master_backup.sql:/docker-entrypoint-initdb.d/master_backup.sql # 自动初始化数据
networks:
- ruoyi-net
depends_on:
- ruoyi-db
开启主从同步
启动新容器
docker-compose up -d ruoyi-db-slave
执行同步指令(使用第 2 步中记录的 File 和 Position)
CHANGE MASTER TO
MASTER_HOST='ruoyi-db',
MASTER_USER='root',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001', -- 替换为你记录的文件名
MASTER_LOG_POS=157; -- 替换为你记录的数字
START SLAVE;
SHOW SLAVE STATUS\G; -- 查看 Slave_IO_Running 和 Slave_SQL_Running 是否都为 Yes

部署elk+filebeat
部署 ELK (Elasticsearch, Logstash, Kibana) + Filebeat 是目前主流的日志管理方案(EFK 堆栈)。 RuoYi 项目中,Filebeat 负责轻量化采集容器日志,Logstash 负责清洗,最后由 Kibana 展示。
更新 docker-compose.yml
services:
# --- Elasticsearch: 存储与索引 ---
elasticsearch:
image: elasticsearch:7.17.9
container_name: elasticsearch
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- ./elk/elasticsearch/data:/usr/share/elasticsearch/data
networks:
- ruoyi-net
ports:
- "9200:9200"
# --- Logstash: 日志处理加工 ---
logstash:
image: logstash:7.17.9
container_name: logstash
volumes:
- ./elk/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
networks:
- ruoyi-net
depends_on:
- elasticsearch
# --- Kibana: 可视化面板 ---
kibana:
image: kibana:7.17.9
container_name: kibana
environment:
- I18N_LOCALE=zh-CN
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
networks:
- ruoyi-net
ports:
- "5601:5601"
depends_on:
- elasticsearch
# --- Filebeat: 轻量级日志采集 ---
filebeat:
image: elastic/filebeat:7.17.9
container_name: filebeat
user: root
volumes:
- ./elk/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro # 采集所有容器日志
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- ruoyi-net
depends_on:
- logstash
核心配置文件
Logstash 配置 (./elk/logstash/logstash.conf)
input {
beats {
port => 5044
}
}
filter {
# 1. 处理 RuoYi 后端 Java 日志 (Spring Boot)
if [container][name] =~ "ruoyi-server" {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:log_time} %{LOGLEVEL:level} %{NUMBER:pid} --- \[%{DATA:thread}\] %{DATA:class} : %{GREEDYDATA:log_content}" }
}
# 针对慢 SQL 的二次解析 (RuoYi 默认会打印执行耗时超过一定阈值的 SQL)
if "slow sql" in [log_content] {
mutate { add_tag => ["slow_sql"] }
}
# 自动识别异常堆栈
if "Exception" in [message] or "Error" in [message] {
mutate { add_tag => ["error_stack"] }
}
}
# 2. 处理 Nginx 访问日志
if [container][name] =~ "ruoyi-nginx" {
grok {
match => { "message" => "%{IPORHOST:client_ip} - %{DATA:remote_user} \[%{HTTPDATE:access_time}\] \"%{WORD:method} %{DATA:url} HTTP/%{NUMBER:http_version}\" %{NUMBER:status} %{NUMBER:body_bytes_sent} \"%{DATA:referrer}\" \"%{DATA:user_agent}\"" }
}
# 将状态码转为数字,方便 Kibana 做范围查询(如查询 400 以上的请求)
mutate {
convert => { "status" => "integer" }
}
# 记录地理位置(需确保 Logstash 容器内有 GeoIP 数据库,可选)
}
}
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
# 动态索引名称,方便按日期管理
index => "ruoyi-%{+YYYY.MM.dd}"
}
# 调试模式:在控制台打印解析后的数据,方便排查配置是否生效
# stdout { codec => rubydebug }
}
Filebeat 配置 (./elk/filebeat/filebeat.yml)
filebeat.inputs:
- type: container
paths:
- /var/lib/docker/containers/*/*.log # 监控宿主机上的容器日志路径
processors:
- add_docker_metadata: ~ # 自动增加容器名称、镜像等元数据
output.logstash:
hosts: ["logstash:5044"]
创建目录并赋权
mkdir -p ./elk/elasticsearch/data
chmod 777 ./elk/elasticsearch/data
启动服务
docker-compose up -d elasticsearch kibana logstash filebeat
访问 Kibana: 浏览器打开 http://你的IP:5601。
-
进入 Stack Management -> Index Patterns。
-
创建一个索引模式
ruoyi-*

更多推荐
所有评论(0)