1、优化前:
目前构建docker镜像都是先执行mvn clean package打包之后,将target目录下的jar包放到服务器上,再通过Dockerfile去build成镜像,步骤多,而且每次都需要登录服务器进行操作,十分麻烦。
2、优化后:
在Spring Boot项目中引入docker-maven-plugin进行相关配置,之后就可以在项目根目录下执行mvn clean package docker:build -DpushImage,就可以在服务器上的docker生成镜像,并且推送到远程仓库上,十分方便,不用每次都登录服务器进行操作。
在进行项目引入docker-maven-plugin之前,先进行docker的配置,使我们能够通过2375端口访问到docker。
Docker的2375端口是默认关闭的,如果我们要使用到它,就需要进行以下的配置:
1、安装有docker的服务器,修改docker.service文件:
vi /etc/systemd/system/docker.service
具体文件所在地,得看你安装docker的位置,如果不知道自己安装在哪里了,执行以下指令去查找:
sudo find / -name docker.service
2、修改docker.service
找到文件以下内容:
ExecStart=/usr/bin/dockerd
修改为:
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
3、重启docker服务
systemctl daemon-reload
systemctl restart docker
4、查看端口是否开启
netstat -anp | grep 2375
如果没有被占用,就什么都不显示
5、如果通过以上配置,发现2375没有开启的话,那么请尝试修改daemon.json文件:
vi /etc/docker/daemon.json
具体文件所在地,得看你安装docker的位置,如果不知道自己安装在哪里了,执行以下指令去查找:
sudo find / -name daemon.json
在配置文件添加上hosts项:
{
"insecure-registries":["xx.xx.xx.xx:5000"],
"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
}
通过以上操作,基本可以打开2375端口,并且可以通过该端口连接上docker,如果还是不行,那么请通过网络查找原因及解决方法了哈。
注意:以上开发的2375端口访问docker的方式是不安全的,如果想要安全的访问,请自行百度了解。
一般我们的镜像除了放在docker上,还可以将其推送到docker registry上,其他服务器上的docker就可以在该docker registry上拉取镜像。
关于docker registry的安装及配置,请参考我的另外一篇博客,这里就不重复去写了:
https://blog.csdn.net/Staba/article/details/124550444?spm=1001.2014.3001.5502
在父工程pom.xml配置如下,如果你不愿意将插件在父工程的pom.xml中进行管理与配置,那么就将以下配置去掉pluginManagemt标签,然后放在子工程中的pom.xml中即可
<!--你的其他配置-->
<profiles>
<profile>
<!--默认激活配置-->
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<imageVersion>${project.version}</imageVersion>
<tag.suffix>dev</tag.suffix>
<docker.host>http://开发环境服务器ip:2375</docker.host>
<docker.registry>开发环境docker registry服务器ip:5000</docker.registry>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<imageVersion>${project.version}</imageVersion>
<tag.suffix>test</tag.suffix>
<docker.host>http://测试环境服务器ip:2375</docker.host>
<docker.registry>测试环境docker registry服务器ip:5000</docker.registry>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<imageVersion>${project.version}</imageVersion>
<tag.suffix>prod</tag.suffix>
<docker.host>http://生产环境服务器ip:2375</docker.host>
<docker.registry>生产环境docker registry服务器ip:5000</docker.registry>
</properties>
</profile>
</profiles>
<build>
<pluginManagement>
<plugins>
<!—如果是springboot项目,引入这个,否则打的jar包大小不正确-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
<!--有需求就绑定,不绑定就更加灵活点-->
<!--<executions>
<!– 当mvn执行install操作的时候,执行docker的build和push –>
<execution>
<id>buildAndPush</id>
<phase>install</phase>
<goals>
<goal>build</goal>
<!– <goal>push</goal>–>
</goals>
</execution>
</executions>-->
<configuration>
<!--docker build 开始-->
<!-- 连接到 带docker环境的linux服务器 编译image -->
<dockerHost>${docker.host}</dockerHost>
<!-- 指定tag版本,可不加,在imageName上指定-->
<!-- <imageTags>-->
<!-- <imageTag>${project.version}</imageTag>-->
<!-- </imageTags>-->
<!-- build 时强制覆盖 tag,配合 imageTags 使用 -->
<!--<forceTags>true</forceTags>-->
<!--
格式:私有仓库/镜像名称:版本号, 如果要执行push操作, 那么镜像名称必须为私有仓库为前缀,且后缀为版本号,不然无效
注意:镜像名称不加:tag, build时会生成latest和你指定版本的两个镜像,加上只生成一个tag为你指定版本的镜像
-->
<imageName>${docker.registry}/${project.artifactId}:${imageVersion}-${tag.suffix}</imageName>
<!--指定dockerfile文件路径-->
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<!-- 用于指定需要复制的文件,需要包含jar包 -->
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<!--docker build 结束-->
<!-- push到 docker hub/registry 开始 -->
<!--serverId 这个是配置在maven的setting.xml中hub/registry的登录账户信息,无密码登录则无需配置-->
<!--<serverId>docker-registry</serverId>-->
<!--docker hub/registry地址-->
<registryUrl>${docker.registry}</registryUrl>
<!--重试推送次数-->
<retryPushCount>3</retryPushCount>
<!--推送超时时间-->
<retryPushTimeout>2000</retryPushTimeout>
<!--是否自動推送到Registry Server, 建議手動推送,开启后build之后就会push,执行mvn时就无需加上-DpushImage -->
<!--<pushImage>true</pushImage>-->
<!-- push到 docker hub 结束 -->
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
如果指定了<serverId>xxx</serverId>,那么请在maven的setting.xml中配置以下信息:
<server>
<id>xxx</id>
<username>your username</username>
<password>your password</password>
<configuration>
<email>you email</email>
</configuration>
</server>
2、子工程引入插件,因为docker相关配置都在父工程中写好了,子工程中无须重复写,只需引入插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3、在<dockerDirectory>标签中指定的路径下创建Dockerfile文件,内容如下:
FROM java
VOLUME /tmp
ENV LANG C.UTF-8
COPY *.jar app.jar
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-Djava.util.Arrays.useLegacyMergeSort=true", "-jar","app.jar"]
4、在子项目根路径上执行mvn clean package -P dev -DimageVersion='1.0.9' docker:build –DpushImage指令,即可将target目录下的jar包构建成镜像,并且推送到docker registry上。
参数解析:
-P dev -> 由于我们在Profile标签中指定了不同环境中使用不同服务器上的docker,所有由该参数指定我们哪个环境的配置生效,默认是dev生效(配置了)。
-DimageVersion='1.0.9' -> 在配置中我们这个属性默认值是当前项目版本,通过该参数指定我们打包镜像的tag最终版本,因为懒的每次去改pom中的version标签,于是自定义一个属性,通过命令行传入版本
docker:build -> 打包完jar之后就会指定docker build指令,将jar包构建成镜像
–DpushImage –> 构建完镜像之后就会将镜像推送到docker registry仓库上
-DpushImageTag -> 如果在<imageTags>中指定了tag,且在<imageName>中没有:tag信息,使用pushImageTag去推送标签指定的tags镜像
当然,如果你懒的去敲docker相关的指令,可以与maven插件的各执行周期绑定,那么就请在executions中进行绑定配置。
通过执行以上的指令,就可以在控制台上看到镜像build的过程以及推送的过程。