本篇文章详细介绍了docker在实际项目中的使用,通过一个单体项目和一个有多个微服务组成的微服务项目来演示
6、使用docker容器化部署项目实战
6-1 在开发工具中使用docker
这个网上有很多教程,不在赘述,看教程吧
(202条消息) IDEA 中配置及使用Docker_傲傲娇的博客-CSDN博客_idea配置docker
(202条消息) Idea:连接Docker服务器_琦彦的博客-CSDN博客_idea连接docker服务器
6-2 部署单体项目
基于若依开发的系统
docker 配置spring boot项目带配置文件_RunMonster的博客-CSDN博客
1、项目介绍
项目除了springboot本身,还需要mysql和redis两个数据库,其他的就没有了
项目结构:
最终的启动jar包在ruoyi-admin模块中
2、构建网络,启动数据库
新建网络
这一个项目所需要的容器都放在一个网络下面,以便他们之间可以通过容器名称连接,而不是通过ip
mysql
docker run -d -p 8136:3306 --network sgdt_network --privileged=true -v /app/mysql/log:/var/log/mysql -v /app/mysql/data:/var/lib/mysql -v /app/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7
命令分析:
docker run
-d #后台启动
-p 8136:3306 #端口映射
--network sgdt_network #指定网络
--privileged=true #挂载数据卷
-v /app/mysql/log:/var/log/mysql #挂载数据卷
-v /app/mysql/data:/var/lib/mysql #挂载数据卷
-v /app/mysql/conf:/etc/mysql/conf.d #挂载数据卷
-e MYSQL_ROOT_PASSWORD=123456 #设置root用户密码
--name mysql #容器名称
mysql:5.7 #镜像名称
这个项目的数据库使用了这个容器卷挂载数据,当有别的项目的需要新的数据库时记得要挂载别的路径,不要两个项目挂载了同一个路径
执行即可上述命令:
太长了,只截取了部分
由于和宿主机的8136端口映射,所以我们通过宿主机ip和端口连接上这个服务器,新建数据库和所需要表即可
到此,mysql安装完成(是不是非常快速)
redis
执行命令:
docker run -d -p 6380:6379 --network sgdt_network --name redis --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data redis:6.0.8 redis-server /etc/redis/redis.conf
命令分析:
docker run
-d #后台运行容器
-p 6380:6379 #端口映射
--network sgdt_network #选择网络
--name redis #容器名称
--privileged=true #挂载数据卷
-v /app/redis/redis.conf:/etc/redis/redis.conf #挂载数据卷
-v /app/redis/data:/data #挂载数据卷
redis:6.0.8 #镜像名称
redis-server /etc/redis/redis.conf #指定操作命令为redis-serve并指定读取宿主机同步过去的配置文件
注意,这里挂载数据卷中指定了redis的配置文件,所以在宿主机的相应路径下应该有一个redis的配置文件,在配置文件中设置我们常用的配置即可
如果使用redis的默认模板,记得更改这些:
运行即可:
可以在外界通过映射的端口连接
3、项目配置和打包
配置文件
在生产环境的配置文件中,可以直接通过容器名称连接容器(在同一个docker网络下)
打包
还是使用不将配置文件(yml)打包进jar,当然也可以当文件打包进jar,看个人习惯就可以,具体springboot选择配置文件的知识看其他笔记即可
<build>
<!--排除yml文件,部署打包的时候使用,平时注释掉(或者放到master分支)-->
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>*.yml</exclude>
</excludes>
</resource>
</resources>
</build>
之后maven打包即可,注意要选择ruoyi-admin下的
4、Dockfile
详细的Dockerfile,之后可以参考这个模板
这里的文件后面我又改了一下,所以可能和下面构建镜像时的截图不太一样,不过无伤大雅
#基础镜像使用java8
FROM java:8
# 作者
MAINTAINER zylai<zylai0712@163.com>
#端口
EXPOSE 8201
# 环境变量
ENV WORK_PATH /sgdt
ENV WORK_CONFIG_PATH /sgdt/config
#工作目录
WORKDIR $WORK_PATH
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
#创建文件夹
RUN mkdir -p $WORK_CONFIG_PATH
# 将jar包添加到容器中并更名为app.jar
ADD /ruoyi-admin/target/ruoyi-admin.jar $WORK_PATH/app.jar
# 拷贝jar包的配置文件到config文件夹下面
ADD /ruoyi-admin/src/main/resources/*.yml $WORK_CONFIG_PATH/
# 进入工作目录,以便直接执行运行jar包的命令(否则还需要手动指定jar的全路径)
RUN cd $WORK_PARH
#修改这个文件的访问时间和修改时间为当前时间,而不会修改文件的内容。
RUN bash -c 'touch app.jar'
# 运行jar包
ENTRYPOINT ["java","-jar","app.jar"]
5、idea一键生成镜像运行容器
需要注意的点就是构建之后运行容器的端口映射和网络
最终会执行的命令:
然后,run!!!
查看容器打印的日志:
通过宿主机映射的端口访问:
一套下来,非常滴爽哈!
6-2 编排容器
就是说上面需要先运行mysql和redis才可以运行我们最终的项目容器sgdt,我们这里就可以通过docker-compose编排来实现上述三个容器的一键运行
docker-compose的诸多优点(直接网上cv的)
- 在单个主机上建立多个隔离环境,Compose 使用项目名称将环境彼此隔离。您可以在多个不同的上下文中使用此项目名称。默认项目名称是项目目录的基本名称。您可以使用
-p 命令行选项或 COMPOSE_PROJECT_NAME 环境变量设置自定义项目名称 。默认项目目录是 Compose 文件的基本目录。可以使用--project-directory 命令行选项自定义项目目录。 - 创建容器时保留卷数据
- 仅重新创建已更改的容器,当您重新启动未更改的服务时,Compose 会使用现有容器。
- 变量在环境之间组合重复使用
docker-compose.yml文件的编写
不再赘述,看别人的博客即可
docker compose 配置文件 .yml 全面指南 - 知乎 (zhihu.com)
version: "3"
services:
# sgdt-service为服务名称,在同一个网络中可以通过服务名称来访问容器,而不通过ip
sgdt-service:
image: sgdt:1.2 #镜像名称
container_name: sgdt01 #容器名称
# 如果上述镜像不存在,就可以根据这里指定的Dockerfile去创建镜像
build:
context: ./
dockerfile: Dockerfile
ports: #指定端口映射
- "8201:8201"
volumes: #挂载容器卷
- /app/sgdt:/data
networks: #指定使用的网络
- sgdt_network
depends_on: #依赖哪些服务,这些服务先启动之后才会启动当前服务
- redis
- mysql
redis:
image: redis:6.0.8
container_name: redis
ports:
- "6380:6379"
volumes:
- /app/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- sgdt_network
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
ports:
- "8136:3306"
volumes:
- /app/mysql/log:/var/log/mysql
- /app/mysql/data:/var/lib/mysql
- /app/mysql/conf:/etc/mysql/conf.d
networks:
- sgdt_network
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks:
sgdt_network:
name: sgdt_network #指定网络名称
关于网络的问题:如果你不指定网络的名称,那么他会默认使用当前路径名+网络名
配置问题
如果直接在idea里面run这个文件,肯定会报错的,就像下面这样
Failed to deploy ‘Compose: docker-compose.yml’: com.intellij.execution.process.ProcessNotCreatedException: Cannot run program “docker-compose” (in directory “XXXXXX”): CreateProcess error=2, 系统找不到指定的文件
这是因为本地没有去配置docker compose,那么就无法连接远程的服务器用远程的docker compose,这个和docker不一样,docker不需要本地的任何配置,只需要直接连接即可
所以这里去配置一下,先下载docker-compose的exe执行程序到本地
下载地址:Releases · mirrors / docker / compose · GitCode
然后在idea的配置里指定刚才的exe文件位置:
一键编排走起
一键走起
6-3 编排多个微服务项目
怎么说呢,微服务和6-2节差别不大,就是docker-compose.yml文件中多加了几个服务
nacos
这里就先使用最简单的启动方式,没有把元数据持久化之类的。
TODO:先挖个坑,以后再填坑
docker run -d --name nacos -p 8848:8848 -e PREFER_HOST_MODE=hostname -e MODE=standalone nacos/nacos-server
docker-compose
version: "3"
services:
# service_device为服务名称,在同一个网络中可以通过服务名称或者容器名称来访问容器,而不通过ip
# build表示如果镜像不存在就根据build去构建
service_device:
image: quest/service_device:1.1 #镜像名称
build:
context: /service/service_device
dockerfile: Dockerfile
container_name: service_device #容器名称
ports:
- "8211:8211"
# volumes: #挂载容器卷
# - /app/quest//sgdt:/data
networks: #指定使用的网络
- quest_network
depends_on: #依赖哪些服务,这些服务先启动之后才会启动当前服务
- nacos
- mysql
service_ucenter:
image: quest/service_ucenter:1.1 #镜像名称
build:
context: /service/service_ucenter
dockerfile: Dockerfile
container_name: service_ucenter
ports:
- "8212:8212"
networks:
- quest_network
depends_on:
- mysql
- nacos
service_qvs:
image: quest/service_qvs:1.1 #镜像名称
build:
context: /service/service_qvs
dockerfile: Dockerfile
container_name: service_qvs
ports:
- "8213:8213"
networks:
- quest_network
depends_on:
- mysql
- nacos
redis:
image: redis:6.0.8
container_name: redis
ports:
- "6380:6379"
volumes:
- /app/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- quest_network
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
container_name: quest_mysql
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
ports:
- "8236:3306"
volumes:
- /app/quest/mysql/log:/var/log/mysql
- /app/quest/mysql/data:/var/lib/mysql
- /app/quest/mysql/conf:/etc/mysql/conf.d
networks:
- quest_network
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
nacos:
image: nacos/nacos-server:latest
container_name: nacos
environment:
PREFER_HOST_MODE: hostname
MODE: standalone
ports:
- "8848:8848"
networks:
- quest_network
networks:
quest_network:
name: quest_network #指定网络名称
也可以在监控工具中查看运行状况
小总结
其实队伍微服务的编排是个很复杂的事情,尤其是依赖过多时。又是也不一定就是部署的时候就新建一个数据库新建一个mq,新建微服务的镜像等,根据实际灵活运用。
不过compose是真的很好用,很好的管理了各个服务