目录
引言
运行若依前后端项目需要的环境有:Java、MySQL、Redis、Nginx(服务器提前打开防火墙)。
本文将演示用CentOS7+Docker部署并运行RuoYi-Vue项目。
本文参考文档为黑马程序员所撰写分享(感谢黑马)。Docker
1. 安装Docker
详细安装配置镜像等操作和注意事项参考:安装Docker(黑马程序员)
2. 搭建Nginx环境:
首先我们要了解什么是数据卷:数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。
容器是隔离环境,容器内程序的文件、配置、运行时产生的容器都在容器内部,我们要读写容器内的文件非常不方便。大家思考几个问题:
-
如果要升级MySQL版本,需要销毁旧容器,那么数据岂不是跟着被销毁了?
-
MySQL、Nginx容器运行后,如果我要修改其中的某些配置该怎么办?
-
我想要让Nginx代理我的静态资源怎么办?
因此,容器提供程序的运行环境,但是程序运行产生的数据、程序运行依赖的配置都应该与容器解耦。
以Nginx为例,我们知道Nginx中有两个关键的目录:
-
html
:放置一些静态资源 -
conf
:放置配置文件
如果我们要让Nginx代理我们的静态资源,最好是放到html
目录;如果我们要修改Nginx的配置,最好是找到conf
下的nginx.conf
文件。
但遗憾的是,容器运行的Nginx所有的文件都在容器内部。所以我们必须利用数据卷将两个目录与宿主机目录关联,方便我们操作。如图:
在上图中:
-
我们创建了两个数据卷:
conf
、html
-
Nginx容器内部的
conf
目录和html
目录分别与两个数据卷关联。 -
而数据卷conf和html分别指向了宿主机的
/var/lib/docker/volumes/conf/_data
目录和/var/lib/docker/volumes/html/_data
目录
这样以来,容器内的conf
和html
目录就 与宿主机的conf
和html
目录关联起来,我们称为挂载。此时,我们操作宿主机的/var/lib/docker/volumes/html/_data
就是在操作容器内的/usr/share/nginx/html/_data
目录。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理了。
小提示:
/var/lib/docker/volumes
这个目录就是默认的存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为/数据卷名/_data
。
为什么不让容器目录直接指向宿主机目录呢?
-
因为直接指向宿主机目录就与宿主机强耦合了,如果切换了环境,宿主机目录就可能发生改变了。由于容器一旦创建,目录挂载就无法修改,这样容器就无法正常工作了。
-
但是容器指向数据卷,一个逻辑名称,而数据卷再指向宿主机目录,就不存在强耦合。如果宿主机目录发生改变,只要改变数据卷与宿主机目录之间的映射关系即可。
不过,我们通过由于数据卷目录比较深,不好寻找,通常我们也允许让容器直接与宿主机目录挂载而不使用数据卷,具体参考搭建MySQL环境。
接下来,我们演示Nginx容器的创建运行以及本地目录挂载:
# 1.首先创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
# 2.然后查看数据卷
docker volume ls
# 结果
DRIVER VOLUME NAME
local 29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f
local html
# 3.查看数据卷详情
docker volume inspect html
# 结果
[
{
"CreatedAt": "2024-05-17T19:57:08+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/html/_data",
"Name": "html",
"Options": null,
"Scope": "local"
}
]
# 4.查看/var/lib/docker/volumes/html/_data目录
ll /var/lib/docker/volumes/html/_data
# 可以看到与nginx的html目录内容一样,结果如下:
总用量 8
-rw-r--r--. 1 root root 497 12月 28 2021 50x.html
-rw-r--r--. 1 root root 615 12月 28 2021 index.html
# 5.进入该目录,并随意修改index.html内容
cd /var/lib/docker/volumes/html/_data
vi index.html
# 6.打开页面,查看效果
# 7.进入容器内部,查看/usr/share/nginx/html目录内的文件是否变化
docker exec -it nginx bash
至此Nginx容器搭建运行以及数据卷挂载到 /var/lib/docker/volumes/html/_data目录下成功。
可以通过ip:80直接访问查看运行情况:
3. 搭建MySQL环境:
接下来,我们演示MySQL容器的创建运行以及本地目录挂载:
在root目录下面创建一个mysql目录在mysql目录里面创建conf和init目录;
conf:里面放配置文件(CNF类型)
下面主要是配置了MySQL的默认编码,改为utf8mb4
[client]
default_character_set=utf8mb4
[mysql]
default_character_set=utf8mb4
[mysqld]
character_set_server=utf8mb4
collation_server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
init:放数据库(SQL类型)
接下来,我们演示本地目录挂载:
# 1.删除原来的MySQL容器
docker rm -f mysql
# 2.进入root目录
cd ~
# 3.创建并运行新mysql容器,挂载本地目录
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v ./mysql/data:/var/lib/mysql \
-v ./mysql/conf:/etc/mysql/conf.d \
-v ./mysql/init:/docker-entrypoint-initdb.d \
mysql
# 4.查看root目录,可以发现~/mysql/data目录已经自动创建好了
ls -l mysql
# 结果:
总用量 4
drwxr-xr-x. 2 root root 20 5月 19 15:11 conf
drwxr-xr-x. 7 polkitd root 4096 5月 19 15:11 data
drwxr-xr-x. 2 root root 23 5月 19 15:11 init
# 查看data目录,会发现里面有大量数据库数据,说明数据库完成了初始化
ls -l data
MySQL安装完毕!通过任意客户端工具即可连接到MySQL。
由于ruoyi-vue里面的sql没有类似下图这样的创建数据库语句所以我们不能直接把sql文件放到init目录下自动初始化数据库,所以我们要手动初始化导入ry-vue数据库:
用数据库可视化工具连接这个数据库,然后手动创建ry-vue数据库以及运行SQL文件导入数据。
4. 搭建Redis环境
拉取Redis镜像:
docker pull redis
创建并运行Redis容器:
docker run -d --name redis -p 6379:6379 redis
可以通过docker ps查看容器的运行状态
5. 构建Java环境运行后端代码:
因为每个容器都是互相隔离的,要使他们能互通所以我们要新创建一个网络并且让我们所有容器都加入该网络。
-
在自定义网络中,可以给容器起多个别名,默认的别名是容器名本身
-
在同一个自定义网络中的容器,可以通过别名互相访问
创建新的网络
docker network create ruoyinet
让nginx、mysql、redis都加入ruoyinet网络
docker network connect ruoyinet nginx
docker network connect ruoyinet mysql
docker network connect ruoyinet redis
然后我们去修改后端代码的配置部分进行打jar包操作:
这里的mysql的IP我们就用容器名字代替,然后填写创建MySQL容器的账号密码。
这里redis的IP我们也用容器名字代替
这里不要忘记更改路径
然后通过idea中的maven可视化操作栏中先clean 然后再package,然后在如图目录下就找到ruoyi-admin.jar文件了
同学们思考一下:以后我们会有很多很多java项目需要打包为镜像,他们都需要Linux系统环境、JDK环境这两层,只有上面的3层不同(因为jar包不同)。如果每次制作java镜像都重复制作前两层镜像,是不是很麻烦。所以,就有人提供了基础的系统加JDK环境,我们在此基础上制作java镜像,就可以省去JDK的配置了:
# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY ruoyi-admin.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
当Dockerfile文件写好以后,就可以利用命令来构建镜像了。
在服务器root目录下创建ruoyi-vue文件夹,把打的ruoyi-admin.jar文件和上面的Dockerfile文件放进去,然后,执行命令,构建镜像:
# 进入镜像目录
cd /root/ruoyi-vue
# 开始构建
docker build -t ruoyi-vue:1.0 .
命令说明:
-
docker build
: 就是构建一个docker镜像 -
-t ruoyi-vue:1.0
:-t
参数是指定镜像的名称(repository
和tag
) -
.
: 最后的点是指构建时Dockerfile所在路径,由于我们进入了ruoyi-vue目录,所以指定的是.
代表当前目录,也可以直接指定Dockerfile目录
镜像创建成功后通过docker images查看镜像。
然后创建容器运行该镜像并加入ruoyi-vue网络:
# 1.创建并运行容器
docker run -d --name ruoyi-vue -p 8080:8080 --network ruoyinet ruoyi-vue:1.0
可以使用docker logs -f ruoyi-vue查看控制台日志。
如果到这里就恭喜你RuoYi-Vue后端代码就运行成功了!
6. 打包前端代码部署运行
先去.env.production文件中修改生产环境的配置
然后在控制台使用命令行进行打包:
npm run build:prod
下图就是打包成功的界面:
打包后的代码在dist目录下:
然后把dist目录下的文件都放到服务器挂在的/var/lib/docker/volumes/html/_data目录下
然后重启一下nginx容器(也可以不重启,个人习惯重启):
#停止
docker stop nginx
#启动
docker start nginx
然后就可以通过服务器IP直接访问到80端口即RuoYi-Vue的前端界面。
至此,你已经学会使用docker部署前后端分离的项目了。
趁热打铁多操作几次吧!
再难不过坚持。
加油,奥里给!