前置工作按照若依官方文档流程操作,在最后docker compose运行的时候发现 ruoyi-server (也就是后端项目的服务) 会启动失败。查看容器启动情况的话会发现除了后端服务异常,其他容器都在正常运行。
这时候有两种情况
- 单独重新启动一下后端的容器,正常运行。
- 单独启动后端容器,依然报错。
下面针对这两种情况分别进行分析
问题分析
重启后端,正常运行
查看一下compose运行的日志可以发现,redis和mysql的容器才刚刚启动就开始运行后端服务容器了,后面的ruoyi-server
和ruoyi-mysql
容器的日志也是交叉的。
再往下看一下日志,发现后面的日志就是在创建数据表等操作,这就说明MySQL其实没有运行完全。所以针对这种情况就是需要让MySQL容器在后端服务启动之前要完全启动。
重启后端,依然报错
查看一下日志发现是MySQL的问题,说是数据库中的表不存在。
进入容器看了一下发现确实没有,然后用source重新加载一下sql脚本文件发现是字符集不支持。
由于本地的数据库是 mysql 8 ,默认的字符集是utfmb4,所以导出的sql脚本在 mysql 5.7 上不能运行,需要修改SQL脚本或者修改MySQL镜像版本
解决方案
关于最后部署失败主要有两个问题,一个是MySQL版本问题,另一个是docker容器启动顺序的问题
MySQL 问题解决
提供两种解决思路,二选其一
修改SQL语句字符集
在本地先把所有包含字符集设置的地方全部删掉,注意SQL语法,不能多删漏删。其他不需要改动
镜像修改成MySQL8
- 修改 mysql-dockerfile,删掉版本
- 修改 docker-compose.yaml,删掉版本
- 后端项目数据库连接串,仅参考。最关键的是加上
allowPublicKeyRetrieval=true&useSSL=false
url: jdbc:mysql://ruoyi-mysql:3306/ruoyi_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
- 这样就不需要修改SQL的字符集了,可以直接使用本地导出的字符集
关于docker容器启动顺序
看了yaml的内容之后发现,明明已经写了 depends_on
,但是mysql还是没有执行完。翻阅一下官方文档发现,需要去看一个启动顺序的文档。
主要是下面这一段,大致内容就是:Compose不会等到容器 “Ready”,只是容器开始运行之后算依赖完成了。如果因为这个遇到了问题,可以使用condition
属性来解决。文档在下面给了四个可选项,这也就是我们解决MySQL容器没有完全运行的办法。
具体的解决方案是在ChatGPT上问的,下面简单描述一下
- 修改 第一行的version,升级到 3.4
- ruoyi-mysql的服务中,添加健康检查机制
- ruoyi-server的depends_on中,修改写法
仅供参考,修改自己的内容
version : '3.4'
services:
ruoyi-mysql:
container_name: ruoyi-mysql
image: mysql
build:
context: .
dockerfile: mysql-dockerfile
ports:
- "3306:3306"
volumes:
- ./mysql/conf:/etc/mysql/conf.d
- ./mysql/logs:/logs
- ./mysql/data:/var/lib/mysql
command: [
'mysqld',
'--innodb-buffer-pool-size=80M',
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci',
'--default-time-zone=+8:00',
'--lower-case-table-names=1'
]
environment:
MYSQL_DATABASE: 'ruoyi_vue'
MYSQL_ROOT_PASSWORD: 123456
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
ruoyi-redis:
container_name: ruoyi-redis
image: redis
build:
context: .
dockerfile: redis-dockerfile
ports:
- "6379:6379"
volumes:
- ./conf/redis.conf:/home/ruoyi/redis/redis.conf
- ./redis/data:/data
command: redis-server /home/ruoyi/redis/redis.conf
ruoyi-nginx:
container_name: ruoyi-nginx
image: nginx
build:
context: .
dockerfile: nginx-dockerfile
ports:
- "80:80"
volumes:
- ./html/dist:/home/ruoyi/projects/ruoyi-ui
- ./conf/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/logs:/var/log/nginx
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- ruoyi-server
links:
- ruoyi-server
ruoyi-server:
container_name: ruoyi-server
build:
context: .
dockerfile: ruoyi-dockerfile
ports:
- "8080:8080"
volumes:
- ./ruoyi/logs:/home/ruoyi/logs
- ./ruoyi/uploadPath:/home/ruoyi/uploadPath
depends_on:
ruoyi-mysql:
condition: service_healthy
ruoyi-redis:
condition: service_started
links:
- ruoyi-mysql
- ruoyi-redis
提醒
在重新 build 和 up 的时候,建议清理一下运行的数据卷挂载目录,防止有其他问题出现。