前阵子帮一个项目组部署若依管理系统,他们之前一直是在服务器上手动传 jar 包、手动装 MySQL、手动配 Redis,每次发版都像在开盲盒——环境稍微不对,整套系统就起不来。后来我把这套若依前后端分离版完整挪进 Docker,用 docker compose 一条命令拉起,测试环境的重复搭建从半天缩到几分钟。这篇文章就把我这次完整落地的过程、配置文件和踩过的坑写下来,给准备用 Docker 部署若依管理系统项目的朋友做参考。下面所有操作都是基于 RuoYi-Vue 前后端分离版,最后会单独讲一下若依微服务版和 plus 版本的部署差异。
1. 先搞清楚若依这个系统由哪几块组成,再谈容器化
很多人一上来就急着写 Dockerfile,结果容器起了一大堆,互相连不上,最后全部推倒重来。我建议先花十分钟把若依的架构在脑子里过一遍,后面的所有操作都会顺畅很多。
1.1 前后端分离版的四个核心组成
若依管理系统前后端分离版拆开看,核心就四块:
- MySQL:存业务数据,默认库名是
ry-vue或ry,项目里自带初始化 SQL 脚本,路径一般在sql/ry_xxx.sql。 - Redis:存验证码、Token 会话、部分缓存数据。若依对 Redis 的依赖比你想的深,Redis 挂掉之后,验证码接口会直接报错,登录都会成问题。
- 后端服务:Spring Boot 打包出来的
ruoyi-admin.jar,默认端口 8080,负责所有业务接口。 - 前端服务:Vue 项目,构建后产生一堆静态文件,由 Nginx 托管,Nginx 再通过反向代理把
/prod-api开头的请求转发到后端。
记住这个结构之后,容器化的思路就很清晰了:MySQL 一个容器、Redis 一个容器、后端一个容器、前端一个容器,四个容器组成一个内部网络,互相通过容器名访问。这就是最标准的若依 Docker 部署拓扑。
1.2 单体版和微服务版的部署思路差异
热搜词里频繁出现“若依微服务 plus”,说明很多人其实在纠结到底部署哪个版本。这里先说结论:如果只是做内部管理系统、OA、后台,用户量不大,优先选若依前后端分离单体版,不要上来就搞微服务。
若依微服务版(RuoYi-Cloud)和 plus 增强版,部署复杂度是几何级上升的。微服务版要额外引入 Nacos 注册中心、Sentinel 限流、Gateway 网关,后端会拆成 ruoyi-gateway、ruoyi-auth、ruoyi-system、ruoyi-job 等多个服务。每个服务一个 jar 包,一个 Docker 镜像,启动顺序还有严格依赖——Nacos 必须先起来,否则所有服务注册不上。这些在容器编排里都能实现,但维护成本完全不是一个量级。
我的建议是:**先用单体版把 Docker 部署这套流程跑通,理解容器网络、数据卷、镜像构建这些核心概念,再考虑微服务化。**本文后面主体流程按单体版讲解,微服务版的编排差异放在第 6 章单独说。
1.3 Docker 化能给若依部署带来什么实际收益
手动部署若依的痛,经历过的人都懂:服务器上 JDK 版本冲突、MySQL 字符集不对、Redis 配置文件改乱、前端 node_modules 污染……每个环境都要重复踩一遍。Docker 化之后,至少有三个立竿见影的好处:
一是环境一致性。镜像把 JDK、Node、Nginx 全都固化进去,本地能跑,测试服务器就一定能跑,不会出现“我这儿好好的,你那儿怎么不行”的玄学问题。
二是部署速度。基础镜像拉下来之后,后端构建一个镜像几分钟,前端构建一个镜像几分钟,docker compose up -d 一条命令全部拉起,重复搭建环境从小时级变成分钟级。
三是回滚简单。发版前把当前镜像打个 tag 留底,新版本出问题,直接用旧的 image tag 再 up -d 一次就恢复了,比在服务器上找旧 jar 快太多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备:安装 Docker 后立刻要做的三件事
2.1 选对 Docker 和 Compose 版本
Linux 服务器上安装 Docker,我一般用官方源安装 docker-ce,不用系统自带的 docker.io,因为自带版本经常比较旧,部分新镜像的特性不支持。安装完成后先确认两件事:
bash复制sudo docker --version
sudo docker compose version
注意,新版 Docker 已经用 docker compose(v2,带空格)替代了老旧的 docker-compose 独立命令。如果你 docker compose version 提示找不到命令,大概率是没装 compose 插件,需要单独安装 docker-compose-plugin 这个包。
Windows 和 Mac 用户直接装 Docker Desktop,后端建议把 WSL 2 集成打开,性能比 Hyper-V 方案好不少。不过我还是推荐用一台 Linux 服务器做正式部署,Docker Desktop 更适合本地开发联调。
2.2 配置镜像加速,避免下载卡死
这是所有新手遇到的第一个大坑:拉取 MySQL、Redis、Nginx 官方镜像时速度感人,或者直接超时。Docker Hub 在境内的访问质量不稳定,解决办法是给 Docker 配置镜像加速源。
Linux 下编辑 /etc/docker/daemon.json:
json复制{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1ms.run"
]
}
保存后重启生效:
bash复制sudo systemctl daemon-reload
sudo systemctl restart docker
Windows 的 Docker Desktop 在 Settings → Docker Engine 里直接编辑 JSON 配置,同样把 registry-mirrors 填进去,Apply & Restart 即可。
需要注意,镜像加速源属于“谁好用谁知道”的东西,不同地区、不同时间可用性差异很大。配置完之后,先用 docker pull mysql:8.0 实测一下,如果还是慢,换别的可用加速地址就行。
2.3 规划宿主机目录与端口占用
正式部署前,先把目录结构规划好,不然容器一多,数据散落在各个随机路径下,想备份都不知道去哪找。我的习惯是统一放到 /opt/ruoyi/ 下:
text复制/opt/ruoyi/
├── mysql/
│ ├── conf/ # MySQL 自定义配置
│ └── data/ # 数据文件,必须持久化
├── redis/
│ └── data/ # Redis 持久化数据
├── sql/ # 若依初始化 SQL 脚本
├── ruoyi-server/ # 后端项目源码(构建用)
├── ruoyi-ui/ # 前端项目源码(构建用)
└── docker-compose.yml # 编排文件
同时检查端口占用情况。若依部署涉及的默认端口有:
| 服务 | 默认端口 | 常见冲突源 |
|---|---|---|
| MySQL | 3306 | 本地已装 MySQL |
| Redis | 6379 | 本地已装 Redis |
| 后端 | 8080 | 其他 Java 服务 |
| 前端 Nginx | 80 | 宿主机 Web 服务 |
bash复制ss -lntp | grep -E '3306|6379|8080|:80 '
发现端口被占用,要么停掉占用方,要么改映射:-p 13306:3306 这种写法把宿主机的 13306 映射到容器内的 3306,数据和配置完全不受影响。
3. 基础设施先跑起来:MySQL 8.0 与 Redis 容器化落地
基础设施一定要先于后端应用部署,否则后端容器一启动就到处找不到数据库和缓存,日志里全是连接失败,排错很痛苦。
3.1 MySQL 容器:数据卷、字符集、初始化脚本一次配齐
先创建目录,再启动容器:
bash复制mkdir -p /opt/ruoyi/mysql/{conf,data}
mkdir -p /opt/ruoyi/sql
# 把若依项目里的 sql/ry_xxx.sql 放到 /opt/ruoyi/sql/
docker run -d \
--name ruoyi-mysql \
--restart always \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD='Ruoyi@123' \
-e TZ=Asia/Shanghai \
-v /opt/ruoyi/mysql/conf:/etc/mysql/conf.d:ro \
-v /opt/ruoyi/mysql/data:/var/lib/mysql \
-v /opt/ruoyi/sql:/docker-entrypoint-initdb.d:ro \
mysql:8.0
这里几个参数都是有讲究的:
-v /opt/ruoyi/mysql/data:/var/lib/mysql是数据持久化的关键。没有这个挂载,容器一删,数据库所有数据灰飞烟灭。这是我见过最多的惨案,没有之一。/docker-entrypoint-initdb.d目录是 MySQL 官方镜像提供的初始化机制。首次启动且数据目录为空时,它会自动执行这个目录下的.sql脚本。所以若依的建库脚本ry_xxx.sql放进去之后,启动即自动建库建表,省去手动导入。注意这个机制只在数据目录为空时触发,如果中途想再导入,得用下面的手动方式。-e TZ=Asia/Shanghai解决容器时区问题,后面第 7 章会详细讲。
如果你想确认初始化是否成功:
bash复制docker exec -it ruoyi-mysql mysql -uroot -p'Ruoyi@123' -e "show databases;"
能看到 ry-vue 这类数据库名字,说明初始化 OK。
另外建议在 mysql/conf/ 下放一个自定义配置,强制字符集,避免后续中文乱码。
ini复制[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
3.2 Redis 容器:密码、持久化、主从一个都不能少
若依默认配置里 Redis 是不带密码的,但这只是让你本地开发方便。部署到服务器上,Redis 裸奔等于把一个没有锁的保险柜摆在门口。启动命令:
bash复制mkdir -p /opt/ruoyi/redis/data
docker run -d \
--name ruoyi-redis \
--restart always \
-p 6379:6379 \
-e TZ=Asia/Shanghai \
-v /opt/ruoyi/redis/data:/data \
redis:7.2 redis-server \
--appendonly yes \
--requirepass 'Ruoyi@123'
--appendonly yes 开启 AOF 持久化,Redis 里的验证码和会话数据不会因为容器重启就全部丢失。--requirepass 设置访问密码,后面要同步改到若依后端的配置里。
如果你对高可用有要求,可以做 Redis 主从。先运行一个 slave 容器,通过 --replicaof ruoyi-master 6379 指定主节点,再配合 --masterauth 声明主节点的密码。实际使用中,若依后端只需要和一个 Redis 地址通信,所以主从对应用层是透明的,挂掉一个只要哨兵或手动切换指向即可。对于绝大多数若依管理系统,单机 Redis 加持久化已经足够,主从可以作为后续演进方向。
3.3 基础设施连通性自测
两个基础服务起来后,先别急着跑后端,花一分钟自测:
bash复制docker ps # 确认两个容器状态都是 Up
docker exec ruoyi-mysql mysqladmin ping -u root -p'Ruoyi@123'
docker exec ruoyi-redis redis-cli -a 'Ruoyi@123' ping
返回 PONG,说明 Redis 正常;MySQL 的 ping 返回成功,说明数据库活着。这一步的 30 秒,能帮你省掉后面半小时的排错时间。
4. 后端镜像构建:改配置、写 Dockerfile、一次打包
4.1 后端到底要改哪几个配置
若依后端的核心配置在 ruoyi-admin/src/main/resources/ 下,两个文件最关键。
application-druid.yml 里的数据源地址,默认是:
yaml复制url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
这里必须把 localhost 改成 MySQL 容器的名称 ruoyi-mysql。因为在 Docker 网络里,容器之间不能通过 localhost 互相访问,localhost 指的是容器自己。
application.yml 里的 Redis 配置,默认是:
yaml复制redis:
host: localhost
port: 6379
同样改成 host: ruoyi-redis,并且加上我们刚才设置的密码:
yaml复制redis:
host: ruoyi-redis
port: 6379
password: 'Ruoyi@123'
顺带说明,JDBC 连接串里的 serverTimezone=GMT%2B8 已经帮我们解决了时区问题,这个配置保留不动。%2B8 是 +8 的 URL 编码,代表东八区。
4.2 多阶段构建 Dockerfile
若依后端是基于 Maven 的 Spring Boot 项目,最稳妥的构建方式是多阶段构建:第一个阶段用 Maven 镜像编译打包,第二个阶段用精简的 JRE 镜像运行。这样最终镜像里不会残留几十个 G 的 Maven 仓库和源码。
在 ruoyi-admin 模块目录(能找到 pom.xml 的那一级)新建 Dockerfile:
dockerfile复制FROM maven:3.8.6-jdk-8 AS builder
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY . .
RUN mvn clean package -DskipTests
FROM openjdk:8-jre-alpine
WORKDIR /app
COPY --from=builder /build/ruoyi-admin/target/ruoyi-admin.jar .
ENV TZ=Asia/Shanghai
EXPOSE 8080
ENTRYPOINT ["java", "-Dfile.encoding=utf-8", "-Duser.timezone=GMT+08", "-jar", "ruoyi-admin.jar"]
注意一个细节:我先把 pom.xml 单独 COPY 进去并执行 mvn dependency:go-offline,再 COPY 全部源码。这样做的目的是利用 Docker 的层缓存——只要 pom.xml 没变,依赖下载这一层就不会重新执行,后续改代码重新构建会快非常多。如果不这么做,每次改一行 Java 代码都要重新下载全部依赖,构建时间能从 3 分钟变成 20 分钟。
4.3 构建与运行
bash复制cd /opt/ruoyi/ruoyi-server
docker build -t ruoyi-server:1.0.0 .
构建成功后,先把后端容器跑起来:
bash复制docker network create ruoyi-net
docker run -d \
--name ruoyi-server \
--network ruoyi-net \
-p 8080:8080 \
-e TZ=Asia/Shanghai \
ruoyi-server:1.0.0
这里创建了一个自定义 bridge 网络 ruoyi-net,后端容器和之前启动的 MySQL、Redis 容器要都接入这个网络,才能通过容器名互相解析。你可能已经注意到,刚才的 MySQL 和 Redis 并没有 --network ruoyi-net 参数。不用急,正式用 docker compose 编排时会在同一个网络下自动处理,这里手动跑主要是为了单独验证后端镜像。
验证方式:
bash复制docker logs -f ruoyi-server
看到 Spring Boot 启动成功的日志,没有数据库或 Redis 连接异常,后端就算齐活。此时可以直接访问 http://服务器IP:8080,理论上会跳到若依的未登录接口,返回一串 JSON 提示“认证失败,无法访问系统资源”,这反而是好消息,说明接口通了。
5. 前端镜像构建:Vue 打包产物加 Nginx 反向代理
5.1 前端构建环境与打包参数
若依前端是标准的 Vue 项目,构建产物是纯静态文件,需要 Node 环境先打包,再用 Nginx 跑。不同版本的若依前端对 Node 版本要求不一样,经典 RuoYi-Vue 的 Vue2 版用 Node 14/16 都行,新版 Vue3 版建议 Node 16+。我的经验是本地装 Node 16 构建最稳,兼容性最好。
构建产物默认输出到 dist/ 目录。若依的 .env.production 里定义了生产环境的接口前缀,默认是 /prod-api。这个前缀不需要改成具体的后端 IP,因为生产环境走的是 Nginx 反向代理,前端所有请求都会以相对路径 /prod-api 发出,由 Nginx 统一转发到后端容器。
5.2 Nginx 配置的核心逻辑
前端容器里的 Nginx 不止要托管静态文件,还要承担反向代理。创建一个 nginx.conf:
nginx复制server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
client_max_body_size 50m;
location / {
try_files $uri $uri/ /index.html;
}
location /prod-api/ {
proxy_pass http://ruoyi-server:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
这里有两个关键点:
一是 location / 块里的 try_files $uri $uri/ /index.html。这是 Vue 单页应用的标准配置,刷新某个子路由时,Nginx 会把请求回退到 index.html,由前端路由接管,否则直接刷新页面会出现 404。
二是 location /prod-api/ 里的 proxy_pass http://ruoyi-server:8080/,注意 proxy_pass 结尾的 / 非常重要。前端请求 /prod-api/login 时,Nginx 会去掉 /prod-api 前缀,转发给后端的 /login。如果漏掉结尾的斜杠,请求会被原样转发成 /prod-api/login,后端没有这个路径,直接 404。这个细节我只想强调一次:斜杠决定前缀是否被剥离。
5.3 前端 Dockerfile 与验证
在 ruoyi-ui 目录下新建 Dockerfile,同样多阶段构建:
dockerfile复制FROM node:16-alpine AS builder
WORKDIR /build
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build:prod
FROM nginx:1.25-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /build/dist /usr/share/nginx/html
EXPOSE 80
构建并运行:
bash复制cd /opt/ruoyi/ruoyi-ui
docker build -t ruoyi-ui:1.0.0 .
docker run -d \
--name ruoyi-ui \
--network ruoyi-net \
-p 80:80 \
ruoyi-ui:1.0.0
然后浏览器访问 http://服务器IP/,能看到若依的登录页、验证码能正常显示、登录流程能走通,整条链路就通了。验证码能出来,说明前端 → Nginx → 后端 → Redis 这条链路是完整的。
6. Docker Compose 编排:从逐个容器到一键拉起
手动 docker run 演示到这一步已经够了,但实际部署不可能每次敲五六个 docker run 命令。把它固化成一个 docker-compose.yml,以后只需一条命令。
6.1 编排文件结构与环境变量
在 /opt/ruoyi/docker-compose.yml 写入:
yaml复制services:
mysql:
image: mysql:8.0
container_name: ruoyi-mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'Ruoyi@123'
TZ: Asia/Shanghai
volumes:
- ./mysql/conf:/etc/mysql/conf.d:ro
- ./mysql/data:/var/lib/mysql
- ./sql:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-pRuoyi@123"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ruoyi-net
redis:
image: redis:7.2
container_name: ruoyi-redis
restart: always
command: redis-server --appendonly yes --requirepass 'Ruoyi@123'
environment:
TZ: Asia/Shanghai
volumes:
- ./redis/data:/data
networks:
- ruoyi-net
server:
build: ./ruoyi-server
container_name: ruoyi-server
restart: always
environment:
TZ: Asia/Shanghai
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
ports:
- "8080:8080"
networks:
- ruoyi-net
ui:
build: ./ruoyi-ui
container_name: ruoyi-ui
restart: always
depends_on:
- server
ports:
- "80:80"
networks:
- ruoyi-net
networks:
ruoyi-net:
driver: bridge
几个要点展开说一下:
depends_on 只是控制启动顺序,不保证依赖服务真正可用。所以我给 MySQL 加了 healthcheck,后端启动条件设为 service_healthy,只有 MySQL 通过 mysqladmin ping 的健康检查后,后端才会启动,这样能避免后端容器先启动、疯狂重试连接数据库的尴尬日志。
所有服务挂在同一个自定义网络 ruoyi-net 下,compose 会自动处理服务名到容器 IP 的 DNS 解析。之前在第 4 章里把后端配置改成 ruoyi-mysql、ruoyi-redis,在 compose 网络里正好对应 service 名。
6.2 启动、更新与回滚
启动整套环境:
bash复制cd /opt/ruoyi
docker compose up -d
查看状态:
bash复制docker compose ps
docker compose logs -f server
日常更新发版只需要两步。假设你改了后端代码:
bash复制docker compose build server
docker compose up -d server
build 会用缓存的依赖层快速产出新镜像,up -d 会用新镜像重建容器,restart: always 策略保证了异常退出自动拉起。
回滚时,如果你给镜像打了版本 tag,比如 ruoyi-server:1.0.0,只需临时修改 compose 里 server 的 image 字段指向旧版本,再 docker compose up -d server,几秒钟回滚到上一个版本。这也是容器化相对手动部署最大的优势。
6.3 微服务版部署的差异
若依微服务版部署,核心差异在两点:一是多了 Nacos 注册中心,二是后端从一个 jar 拆成多个服务。Nacos 本身也可以容器化:
bash复制docker run -d --name ruoyi-nacos -p 8848:8848 -e MODE=standalone nacos/nacos-server:v2.3.0
如果你的 compose 里同时有 Nacos、Gateway、System、Auth 等多个服务,depends_on 会变得非常复杂——所有服务都要等 Nacos 起来并完成注册才能正常工作。实践中我会先启动 Nacos,等服务端所有服务在 Nacos 控制台注册成功后,再启动网关,最后启动前端。这个过程没法完全靠 depends_on 解决,需要在启动脚本里加探测逻辑。
所以再次建议:纯管理系统,老老实实用单体版。微服务版部署一次也许能成功,但后续每次发版、每次排障,复杂度都是单体版的数倍。如果团队没有明确的微服务红利可以吃到,不值得为技术热度买单。
7. 部署后的坑与排查:这些我全踩过
最后一章,把我在实际部署中反复踩到的坑集中写出来。这些问题几乎每个人都会遇到,提前知道可以省掉大量排错时间。
7.1 时区错乱:定时任务半夜执行、日志时间差 8 小时
症状:登录日志、操作日志的时间比北京时间慢 8 小时;若依的定时任务(代码生成、数据清理)在错误的时间点触发。
原因:Docker 官方基础镜像默认时区是 UTC,也就是零时区,和北京时间差 8 小时。
解决:三个层面同时设置,最保险。Dockerfile 里 ENV TZ=Asia/Shanghai,compose 里 environment: TZ: Asia/Shanghai,Java 启动参数加 -Duser.timezone=GMT+08。JDBC 连接串里的 serverTimezone 也要对应。我见过只改 JDBC 不换系统时区的情况,日志正确但定时任务还是错的,所以三层全部安排上。
7.2 MySQL 8 认证插件导致的连接拒绝
症状:后端日志报 Access denied for user 'root'@'...' 或 Public Key Retrieval is not allowed。
原因:MySQL 8 默认的认证插件是 caching_sha2_password,如果若依项目用的数据库驱动版本较老(5.x 的 mysql-connector-java),无法兼容这个插件。
解决:简单粗暴的就是把 root 用户的认证方式改回老协议:
sql复制ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'Ruoyi@123';
FLUSH PRIVILEGES;
如果不想改认证,就在 JDBC 连接串里加两个参数:
text复制useSSL=false&allowPublicKeyRetrieval=true
allowPublicKeyRetrieval=true 让客户端在连接时主动获取服务器的 RSA 公钥,避免密钥交换失败。我做的项目里,两种方案都验证过,推荐优先改连接串,不要动数据库用户,因为 mysql_native_password 在 MySQL 8.4 中已经被标记为废弃,面向未来用连接串方案更合适。
7.3 容器间用 localhost 互相访问永远失败
这个坑基本每个刚接触 Docker 的人都会踩:后端容器里访问 localhost:3306,报连接拒绝。原因很简单:localhost 是容器自己,不是宿主机的 localhost,更不是别的容器。容器之间只有通过同一个网络下容器名(或服务名)才能解析互访。
所以反复强调:**只要后端配置里 MySQL 和 Redis 的 host 还写着 localhost 或 127.0.0.1,Docker 环境就一定连不上。**我一般先全局搜索项目里的 localhost,把所有数据库和缓存的地址改成容器服务名,再开始构建镜像。
7.4 镜像下载慢、依赖拉取慢
镜像下载慢的解法前面讲了,配置 registry-mirrors。这里补充一个更隐蔽的问题:Maven 和 npm 依赖下载也慢。
后端构建时,Maven 会去中央仓库拉依赖,如果网速不佳,mvn package 可能要跑十几分钟。解决方法是给 Maven 设置国内镜像源,在项目的 .mvn/settings.xml 里配置阿里云镜像仓库的 mirror,或者在 pom.xml 里把远程仓库地址改掉。前端同理,.npmrc 里设置 npm 镜像源:
text复制registry=https://registry.npmmirror.com
构建速度和舒心程度是完全不同的体验。
7.5 数据持久化与容器维护
最后强调一个最容易被忽略的问题:**只要没挂载数据卷,容器删除等于数据全部删除。**MySQL 的 /var/lib/mysql、Redis 的 /data,必须在启动参数或 compose 里挂载到宿主机目录。我经历过一次误操作,直接把 MySQL 容器删了,整个项目的业务数据全部没了,还好有备份才救了回来。
养成定期备份的习惯,利用容器执行 mysqldump 非常方便:
bash复制docker exec ruoyi-mysql sh -c 'exec mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" --databases ry-vue' > /opt/ruoyi/backup/ry_$(date +%F).sql
配合 crontab 定时执行,就能保证数据库每天有备份。
另外,容器运行久了,宿主机磁盘会被废弃镜像、悬空卷占满,定期执行 docker system prune -f 清理无用资源,是我的常规操作。
最后再分享一个我自己养成的习惯:整套 compose 文件和配置准备好之后,我会把 /opt/ruoyi 整个目录用 git 管理起来,docker-compose.yml、nginx.conf、MySQL 的配置变更都提交版本。这样无论换服务器还是重新搭建环境,git clone 下来 docker compose up -d 就完事,数据库初始化和持久化数据都规划好了,一个全新的若依环境十几分钟就能跑起来。希望这篇记录能帮你少踩几个坑,一次部署成功。
