目錄java
docker-maven-plugin 介紹
環境、軟件準備
Demo 示例
配置 DOCKER_HOST
示例構建鏡像
指定構建信息到 POM 中構建
使用 Dockerfile 構建
使用命令
綁定 Docker 命令到 Maven各個階段
使用私有Docker倉庫地址
安全認證配置
FAQ
一、docker-maven-plugin 介紹git
在咱們持續集成過程當中,項目工程通常使用 Maven 編譯打包,而後生成鏡像,經過鏡像上線,可以大大提供上線效率,同時可以快速動態擴容,快速回滾,着實很方便。docker-maven-plugin 插件就是爲了幫助咱們在Maven工程中,經過簡單的配置,自動生成鏡像並推送到倉庫中。docker
二、環境、軟件準備apache
本次演示環境,我是在本機 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,這裏忽略安裝過程。安全
三、Demo 示例maven
3.1 配置 DOCKER_HOSTtcp
docker-maven-plugin 插件默認鏈接本地 Docker 地址爲:localhost:2375,因此咱們須要先設置下環境變量。測試
DOCKER_HOST=tcp://<host>:2375
1
注意:若是沒有設置 DOCKER_HOST 環境變量,能夠命令行顯示指定 DOCKER_HOST 來執行,如我本機指定 DOCKER_HOST:DOCKER_HOST=unix:///var/run/docker.sock mvn clean install docker:build。ui
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.com</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>
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
3.2.2 使用 Dockerfile 構建
pom.xml配置
<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.com
WORKDIR /ROOT
CMD ["java", "-version"]
ENTRYPOINT ["java", "-jar", "${project.build.finalName}.jar"]
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
以上兩種方式執行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.com
---> 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
執行完成後,使用docker images查看生成的鏡像:
REPOSITORY TAG IMAGE ID CREATED SIZE
mavendemo latest 333b429536b2 38 minutes ago 643 MB
1
2
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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.com</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>
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
45
46
47
48
49
50
51
52
53
54
以上示例,當咱們執行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 插件咱們也是很容易實現,有幾種方式實現:
1、修改 POM 文件 imageName 操做
...
<configuration>
<imageName>registry.example.com/wanyang3/mavendemo:v1.0.0</imageName>
...
</configuration>
...
1
2
3
4
5
6
2、修改 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>registry.example.com/wanyang3/mavendemo:v1.0.0</newName>
</configuration>
</execution>
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
3.6 安全認證配置
當咱們 push 鏡像到 Docker 倉庫中時,不論是共有仍是私有,常常會須要安全認證,登陸完成以後才能夠進行操做。固然,咱們能夠經過命令行 docker login -u user_name -p password docker_registry_host 登陸,可是對於自動化流程來講,就不是很方便了。使用 docker-maven-plugin 插件咱們能夠很容易實現安全認證。
首先在 Maven 的配置文件 setting.xml 中增長相關 server 配置,主要配置 Docker registry用戶認證信息。
<servers>
<server>
<id>my-docker-registry</id>
<username>wanyang3</username>
<password>12345678</password>
<configuration>
<email>wanyang3@mail.com</email>
</configuration>
</server>
</servers>
1
2
3
4
5
6
7
8
9
10
而後只須要在 pom.xml 中使用 server id 便可。
<plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<imageName>registry.example.com/wanyang3/mavendemo:v1.0.0</imageName>
...
<serverId>my-docker-registry</serverId>
</configuration>
</plugin>
</plugins>
1
2
3
4
5
6
7
8
9
10
11
12
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
四、FAQ
一、執行 build images 時,報錯狀況一:
[INFO] Building image mavendemo
org.apache.http.impl.execchain.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: java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: java.io.IOException: No such file or directory -> [Help 1]
1
2
3
4
這個是由於 Docker 服務沒有啓動形成的,啓動 Docker 便可。
二、執行 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]1這個是由於鏡像名字不正確,Docker 鏡像名稱需匹配[a-z0-9-_.]。