写在前面

本篇在第二篇《整合Swagger-UI实现在线API文档》的基础上,使用Maven插件为SpringBoot应用构建Docker镜像,并上传至私有镜像仓库Docker Registry中。

Docker Registry

开发者可以使用Docker提供的registry这一镜像来搭建属于自己的私有仓库,这里选择版本为2的镜像即可,先将其下载到本地:

1
docker pull registry:2

这里有它的快速使用方法,其实就是一条命令:

执行下面的命令即可创建一个私有仓库:

1
docker run -d -p 5000:5000 --restart=always --name registry2 registry:2

Docker开启远程API

打开docker.service文件:

1
vi /usr/lib/systemd/system/docker.service

将其中的如下代码:

1
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

修改为如下所示:

1
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock

让Docker支持http上传镜像

使用如下命令来让Docker支持http上传镜像:

1
echo '{ "insecure-registries":["192.168.51.160:5000"] }' > /etc/docker/daemon.json

修改完上述配置信息后,接下来需要使用如下命令来让配置生效:

1
systemctl daemon-reload

接着重启Docker服务:

1
2
systemctl stop docker
systemctl start docker

最后开启防火墙的Docker构建端口,使用的命令如下:

1
2
firewall-cmd --zone=public --add-port=2375/tcp --permanent
firewall-cmd --reload

使用Maven构建Docker镜像

再次强调,本篇代码是在第二篇《整合Swagger-UI实现在线API文档》的基础上进行修改的。

开发者可以复制一份shop-swagger-ui源码,将其名字修改为shop-docker,然后对应包和文件中的信息也记得修改,本篇后续所有操作均在shop-docker这一Module中进行。

第一步,在POM文件中新增docker-maven-plugin依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<imageName>myshop-all/${project.artifactId}:${project.version}</imageName>
<dockerHost>http://192.168.51.160:2375</dockerHost>
<baseImage>openjdk:8u102</baseImage>
<entryPoint>["java", "-jar","/${project.build.finalName}.jar"]
</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>

解释一下上述配置信息:
(1)executions.execution.phase表示配置在maven打包应用时构建docker镜像;
(2)imageName用于指定镜像名称,其中myshop-all是仓库名称,${project.artifactId}是镜像名称,${project.version}是仓库名称;
(3)dockerHost表示设置镜像打包后上传的docker服务器地址;
(4)baseImage表示该应用所依赖的基础镜像,此处为openjdk:8u102;
(5)entryPoint表示设置docker容器启动时执行的命令;
(6)resources.resource.targetPath表示将打包后的资源文件复制到该目录;
(7)resources.resource.directory表示待复制的文件所在的目录,注意Maven打包的应用jar包会保存在target目录下;
(8)resources.resource.includ表示需要复制的文件,即打包好的应用的jar包。

第二步,修改application.yml配置文件,将其中的localhost修改为db:

1
2
3
4
5
6
7
8
9
10
11
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://db:3306/shop?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: envy123
mybatis:
mapper-locations:
- classpath:mapper/*.xml
- classpath*:com/**/mapper/*.xml

实际上,我们可以将docker中的容器看做独立的虚拟机,这样shop-docker访问localhost时就不会访问到mysql,但是容器之间可通过指定服务名称来进行访问,如db,注意db这个名称需要在运行shop-docker容器时进行指定。

第三步,使用IDEA打包项目并构建镜像,请注意依赖的基础镜像需要先下载到本地,否则会出现镜像构建超时的情况。接着执行maven的package命令来构建镜像:

可以看到镜像构建成功:

同时查看一下宿主机,可以看到宿主机上显示已经存在了该镜像:

运行shop-docker服务

启动MySQL服务

第一步,下载MySQL5.7的docker镜像:

1
docker pull mysql:5.7

第二步,创建对应目录:

1
2
3
mkdir -p /mydata/mysql/log
mkdir -p /mydata/mysql/data
mkdir -p /mydata/mysql/conf

第三步,启动MySQL服务:

1
2
3
4
5
docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=envy123 \
-d mysql:5.7

简单解释一下参数含义:
(1)-p 3306:3306,表示将容器的3306端口映射到宿主机的3306端口,注意格式为“宿主机端口:容器端口”;
(2)-v /mydata/mysql/log:/var/log/mysql,表示将容器的日志文件夹挂载到宿主机,注意格式为“宿主机:容器;
(3)-v /mydata/mysql/data:/var/lib/mysql,表示将容器的数据文件夹挂载到宿主机,注意格式为“宿主机:容器;
(4)-e MYSQL_ROOT_PASSWORD=envy123,表示初始化容器中root用户的密码。

第四步,进入到运行MySQL服务的docker容器中:

1
docker exec -it mysql /bin/bash

第五步,使用MySQL命令进入客户端:

1
mysql -uroot -penvy123 --default-character-set=utf8

第六步,创建shop数据库:

1
create database shop character set utf8;

第七步,打开一个新的终端,安装上传下载插件,将shop.sql文件上传到Linux服务器上,可指定目录为/mydata

1
yum -y install lrzsz

然后将shop.sql文件拷贝到mysql容器的/目录下:

1
docker cp /mydata/shop.sql mysql:/

接着进入到第六步中的sql命令环境,将shop文件导入到数据库:

1
2
use shop;
source /shop.sql;

第八步,root的账号的权限,使得任何ip都能访问到:

1
grant all privileges on *.* to 'root'@'%';

这样就完成了MySQL的启动服务。

启动shop-docker应用服务

第一步,创建对应目录:

1
mkdir -p /mydata/app/shop-docker/logs

第二步,使用如下命令来启动该服务,注意这里我们需要使用--link参数来让应用使用db域名来访问MySQL服务:

1
2
3
4
5
docker run -p 8080:8080 --link mysql:db \
-v /etc/localtime:/etc/localtime \
-v /mydata/app/shop-docker/logs:/var/logs \
--name shop-docker \
-d myshop-all/shop-docker:0.0.1-SNAPSHOT

第三步,开放8080端口(注意只有当防火墙是运行状态下才需要进行此操作):

1
2
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload

第四步,打开浏览器,访问http://宿主机IP:8080/swagger-ui.html连接,查看shop-docker服务是否已经正常启动:

然后我们测试一下“获取所有的品牌信息”的接口,可以看到数据是可以正常返回的:

这样我们就完成了使用Maven插件为SpringBoot应用构建Docker镜像,并运行项目这一功能。