Maven插件docker-maven-plugin的使⽤
⽬录
1、docker-maven-plugin 介绍
2、环境、软件准备
3、Demo ⽰例
3.1 配置 DOCKER_HOST
3.2 ⽰例构建镜像
3.3 执⾏命令
3.4 绑定Docker 命令到 Maven 各个阶段
3.5 使⽤私有 Docker 仓库地址
3.6 安全认证配置
3.7 其他参数
4、FAQ
参考资料
1、docker-maven-plugin 介绍
在我们持续集成过程中,项⽬⼯程⼀般使⽤ Maven 编译打包,然后⽣成镜像,通过镜像上线,能够⼤⼤提供上线效率,同时能够快速动态扩容,快速回滚,着实很⽅便。docker-maven-plugin 插件就是为了帮助我们在Maven⼯程中,通过简单的配置,⾃动⽣成镜像并推送到仓库中。
2、环境、软件准备
本次演⽰环境,我是在本机 Mac OX 上操作,以下是安装的软件及版本:
Docker:version 17.03.1-ce
Maven:version 3.3.9
Java: version 1.8.0_91
docker-maven-plugin:1.0.0
注意:这⾥我们要测试 Java Maven 项⽬⽤ docker-maven 插件打镜像,上传镜像等操作,所以需要先安装⼀下 Docker、Maven、Java,这⾥忽略安装过程。
3、Demo ⽰例
3.1 配置 DOCKER_HOST
docker-maven-plugin 插件默认连接本地 Docker 地址为:localhost:2375,所以我们需要先设置下环境变量。
DOCKER_HOST=tcp://<host>:2375
注意:如果没有设置 DOCKER_HOST 环境变量,可以命令⾏显⽰指定 DOCKER_HOST 来执⾏,如我本机指定DOCKER_HOST:DOCKER_HOST=unix:///var/run/docker.sock mvn clean install docker:build。
3.2 ⽰例构建镜像
构建镜像可以使⽤⼀下两种⽅式,第⼀种是将构建信息指定到 POM 中,第⼆种是使⽤已存在的 Dockerfile 构建。
第⼀种⽅式,⽀持将 FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD 信息配置在 POM 中,不需要使⽤ Dockerfile 配置。但是如果使⽤ VOLUME 或其他 Dockerfile 中的命令的时候,需要使⽤第⼆种⽅式,创建⼀个 Dockerfile,并在 POM 中配置 dockerDirectory 来指定路径即可。
这⾥我们以⼀个 Java Maven 项⽬ mavendemo 作为⽰例演⽰⼀下。
3.2.1 指定构建信息到 POM 中构建
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<imageName>mavendemo</imageName>
<baseImage>java</baseImage>
<maintainer>docker_maven docker_maven@email</maintainer>
<workdir>/ROOT</workdir>
<cmd>["java", "-version"]</cmd>
<entryPoint>["java", "-jar", "${project.build.finalName}.jar"]</entryPoint>
<!-- 这⾥是复制 jar 包到 docker 容器指定⽬录配置 -->
<resources>
<resource>
<targetPath>/ROOT</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
3.2.2 使⽤ Dockerfile 构建
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<imageName>mavendemo</imageName>
<dockerDirectory>${basedir}/docker</dockerDirectory> <!-- 指定 Dockerfile 路径-->                <!-- 这⾥是复制 jar 包到 docker 容器指定⽬录配置,也可以写到 Docokerfile 中 -->                <resources>
<resource>
<targetPath>/ROOT</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
${basedir}/docker/Dockerfile 配置
FROM java
MAINTAINER docker_maven docker_maven@email
如何配置maven环境变量WORKDIR /ROOT
CMD ["java", "-version"]
ENTRYPOINT ["java", "-jar", "${project.build.finalName}.jar"]
以上两种⽅式执⾏docker:build效果是⼀样的,执⾏输出过程⼤致如下:[INFO] --- docker-maven-plugin:1.0.0:build (default-cli) @ mavenDemo ---
[INFO] Building image mavendemo
Step 1/5 : FROM java
---> d23bdf5b1b1b
Step 2/5 : MAINTAINER docker_maven docker_maven@email
---> Using cache
---> 2faf180d4a50
Step 3/5 : WORKDIR /ROOT
---> Using cache
---> 862210f7956a
Step 4/5 : ENTRYPOINT java -jar mavenDemo.jar
---> Running in 96bbe83de6ec
---> c29009c88993
Removing intermediate container 96bbe83de6ec
Step 5/5 : CMD java -version
---> Running in f69b8d2a75b1
---> bc8d54014325
Removing intermediate container f69b8d2a75b1
Successfully built bc8d54014325
执⾏完成后,使⽤docker images查看⽣成的镜像:
REPOSITORY      TAG          IMAGE ID            CREATED            SIZE
mavendemo        latest        333b429536b2        38 minutes ago      643 MB
3.3 执⾏命令
mvn clean package docker:build只执⾏ build 操作
mvn clean package docker:build -DpushImage 执⾏ build 完成后 push 镜像
mvn clean package docker:build -DpushImageTag 执⾏ build 并 push 指定 tag 的镜像
注意:这⾥必须指定⾄少⼀个 imageTag,它可以配置到 POM 中,也可以在命令⾏指定。命令⾏指定如下:mvn clean package docker:build -DpushImageTags -DdockerImageTags=imageTag_1 -DdockerImageTags=imageTag_2,POM ⽂件中指定配置如下:
<build>
<plugins>
...
<plugin>
<configuration>
...
<imageTags>
<imageTag>imageTag_1</imageTag>
<imageTag>imageTag_2</imageTag>
</imageTags>
</configuration>
</plugin>
...
</plugins>
</build>
3.4 绑定Docker 命令到 Maven 各个阶段
我们可以绑定 Docker 命令到 Maven 各个阶段,我们可以把 Docker 分为 build、tag、push,然后分别绑定 Maven 的package、deploy 阶段,此时,我们只需要执⾏mvn deploy就可以完成整个 build、tag、push操作了,当我们执⾏mvn build 就只完成 build、tag 操作。除此此外,当我们想跳过某些步骤或者只执⾏某个步骤时,不需要修改 POM ⽂件,只需要指定跳过 docker 某个步骤即可。⽐如当我们⼯程已经配置好了⾃动化模板了,但是这次我们只需要打镜像到本地⾃测,不想执⾏push 阶段,那么此时执⾏要指定参数-DskipDockerPush就可跳过 push 操作了。
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<imageName>mavendemo</imageName>
<baseImage>java</baseImage>
<maintainer>docker_maven docker_maven@email</maintainer>
<workdir>/ROOT</workdir>
<cmd>["java", "-version"]</cmd>
<entryPoint>["java", "-jar", "${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/ROOT</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
<execution>
<id>tag-image</id>
<phase>package</phase>
<goals>
<goal>tag</goal>
</goals>
<configuration>
<image>mavendemo:latest</image>
<newName>docker.io/wanyang3/mavendemo:${project.version}</newName>
</configuration>
</execution>
<execution>
<id>push-image</id>
<phase>deploy</phase>
<goals>
<goal>push</goal>
</goals>
<configuration>
<imageName>docker.io/wanyang3/mavendemo:${project.version}</imageName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
以上⽰例,当我们执⾏mvn package时,执⾏ build、tag 操作,当执⾏mvn deploy时,执⾏build、tag、push 操作。如果我们想跳过 docker 某个过程时,只需要:
-DskipDockerBuild 跳过 build 镜像
-DskipDockerTag 跳过 tag 镜像
-DskipDockerPush 跳过 push 镜像
-DskipDocker 跳过整个阶段
例如:我们想执⾏ package 时,跳过 tag 过程,那么就需要mvn package -DskipDockerTag。
3.5 使⽤私有 Docker 仓库地址
实际⼯作环境中,我们需要 push 镜像到我们私有 Docker 仓库中,使⽤d ocker-maven-plugin 插件我们也是很容易实现,有⼏种⽅式实现:
⼀、修改 POM ⽂件 imageName 操作
...
<configuration>
<imageName&le/wanyang3/mavendemo:v1.0.0</imageName>
...
</configuration>
...
⼆、修改 POM ⽂件中 newName 操作
...
<configuration>
<imageName>mavendemo</imageName>
...
</configuration>
<execution>
<id>tag-image</id>
<phase>package</phase>
<goals>
<goal>tag</goal>
</goals>
<configuration>
<image>mavendemo</image>
<newName&le/wanyang3/mavendemo:v1.0.0</newName>
</configuration>
</execution>
...
3.6 安全认证配置
当我们 push 镜像到 Docker 仓库中时,不管是共有还是私有,经常会需要安全认证,登录完成之后才可以进⾏操作。当然,我们可以通过命令⾏ docker login -u user_name -p password docker_registry_host 登录,但是对于⾃动化流程来说,就不是很⽅便了。使⽤ docker-maven-plugin 插件我们可以很容易实现安全认证。
⾸先在 Maven 的配置⽂件 l 中增加相关 server 配置,主要配置 Docker registry⽤户认证信息。<servers>
<server>
<id>my-docker-registry</id>
<username>wanyang3</username>
<password>12345678</password>
<configuration>
<email>wanyang3@mail</email>
</configuration>
</server>
</servers>
然后只需要在 l 中使⽤ server id 即可。
<plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<imageName&le/wanyang3/mavendemo:v1.0.0</imageName>
...
<serverId>my-docker-registry</serverId>
</configuration>
</plugin>
</plugins>
3.7 其他参数
docker-maven-plugin 插件还提供了很多很实⽤的配置,稍微列举⼏个参数吧。
参数说明默认值
<forceTags>true</forceTags>build 时强制覆盖 tag,配合 imageTags 使⽤false <noCache>true</noCache>build 时,指定 –no-cache 不使⽤缓存false <pullOnBuild>true</pullOnBuild>build 时,指定 –pull=true 每次都重新拉取基础镜像false <pushImage>true</pushImage>build 完成后 push 镜像false <pushImageTag>true</pushImageTag>build 完成后,push 指定 tag 的镜像,配合 imageTags 使⽤false <retryPushCount>5</retryPushCount>push 镜像失败,重试次数5
<retryPushTimeout>10</retryPushTimeout>push 镜像失败,重试时间10s <rm>true</rm>build 时,指定 –rm=true 即 build 完成后删除中间容器false
<useGitCommitId>true</useGitCommitId>build 时,使⽤最近的 git commit id 前7位作为tag,例如:image:b50b604,前提
是不配置 newName
false
4、FAQ
1、执⾏ build images 时,报错情况⼀:
[INFO] Building image mavendemo
org.apache.hain.RetryExec execute
I/O exception (java.io.IOException) caught when processing request to {}->unix://localhost:80: No such file or directory
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.0.0:build (default-cli) on project mavenDemo: Exception caught: urrent.ExecutionException:
com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: java.io.IOException: No such file or directory -> [Help 1]
这个是因为 Docker 服务没有启动造成的,启动 Docker 即可。
2、执⾏ build images 时,报错情况⼆:
ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.0.0:build (default-cli) on project mavenDemo: Exception caught: Request error: POST unix://localhost:80/build?t=mavenDemo: 500, body: {"message":"Error parsing reference: \"mavenDemo\" is not a valid repository/tag: repository name must be lowercase"}: HTTP 500 Internal Server Error -> [Help 1]