docker-maven-plugin初探
背景
最近想搞持續整合測試,初步構想是使用git、jekins、maven、docker作為持續整合的基礎元件,當然也是最常用的基礎元件。
初步是想將java的測試用例塞到docker容器中進行測試,測試環境部署只一次就好,映象推送到倉庫,隨測隨拉,直接使用docker命令執行,好處是環境一致,不需要重新部署測試程式碼所依附的環境;壞處是docker,docker,docker,也就是想執行測試用例必備的基礎環境docker。
junit的命令列執行
我們最常見的執行測試用例多數是通過eclipse的run as,或者是mvn test執行測試用例。如果將測試用例塞到容器內,要麼將mvn裝到容器內,要麼在物理機構建,並將構建後的環境也就是jar包塞到容器內使用java執行。
衡量了下,還是決定在物理機進行構建,將構建結果塞到容器內.
1. 重複構建mvn環境浪費時間;
2. 將mvn塞到容器內浪費資源;
3. blablabla,反正就是不爽
鑑於本人學藝不精,這裡轉載一篇對於junitcore使用的文章:
命令列執行使用java -cp *.jar org.junit.runner.JUnitCore classname可參考該篇文章瞭解及執行。
執行示例
使用junit簡單的輸出語句,沒有功能,只是作為示例演示:
public class startTest {
@Before
public void setup(){
System.out.println("this is setup...");
}
@After
public void teardown(){
System.out .println("this is teardown...");
}
@Test
public void test1(){
System.out.println("this is test1...");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
命令列之行junit:
java -cp $CLASS_PATH:target/test-classes org.junit.runner.JUnitCore $CLASS_NAME
- 1
遇到的問題及解決辦法
由於對java執行junit測試用例實在不是很熟,mvn打完包後,執行
java -cp $CLASS_PATH org.junit .runner.JUnitCore $CLASS_NAME
- 1
總是找不到測試類(本人技術不熟,噴子勿噴^o^),原因是由於jar包內預設查詢的是src/main下的檔案,而測試用例大都在src/test下
mv src/test src/main
mvn clean package -DskipTests=true
java -cp $CLASS_PATH org.junit.runner.JUnitCore $CLASS_NAME
bingo
- 1
- 2
- 3
- 4
或者指定classpath,指定去target/test-classes目錄下查詢測試類
java -cp $CLASS_PATH:target/test-classes org.junit.runner.JUnitCore $CLASS_NAME
- 1
進入主題
該外掛有兩種使用方式:
1. 不使用dockerfile
2. 使用dockerfile
不使用dockerfile
顧名思義就是不依賴於dockerfile構建映象,即通過標籤來定義映象構建過程。
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>registry.test.com/example</imageName>
<baseImage>registry.test.com/base_image</baseImage>
<entryPoint>["sh", "start.sh"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>**/*</include>
</resource>
</resources>
</configuration>
</plugin>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
其中:
imageName:即將構建的映象名
baseImage: 構建映象時需要的基礎映象,類似於Dockerfile的From
entryPoint: 容器啟動時執行的命令
resources:拷貝一些額外的檔案到指定路徑下,比如${project.build.finalName}.jar
檔案
一些maven的內建變數
${basedir} 專案根目錄
${project.build.directory} 構建目錄,預設為target
${project.build.outputDirectory} 構建過程輸出目錄,預設為target/classes,target/test-classes
${project.build.finalName} 打包後生成的結果名稱,預設為${project.artifactId}-${project.version}
\${project.packaging} 打包型別,預設為jar
maven一些標籤
targetPath:指定build資源到哪個目的目錄,預設是base directory
directory:指定屬性檔案的目錄,build的過程需要找到它,並且將其放到targetPath下。
includes:指定包含檔案的patterns,符合樣式並且在directory目錄下的檔案將會是包含進project的資原始檔
excludes:指定不包含在內的patterns,如果includes與excludes有衝突,那麼excludes勝利,那些符合衝突樣式的檔案還是不會包含進來的
使用dockerfile
依賴於Dockerfile構建映象,需指定dockerDirectory
來查詢Dockerfile所在檔案目錄,指定dockerDirectory
後,baseImage
, maintainer
, cmd
和entryPoint
等標籤均失效。dockerDirectory
目錄下的所有內容預設會被複制到${project.build.directory}/docker
目錄下。
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>registry.test.com/example</imageName>
<dockerDirectory>${project.basedir}/</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
我的根目錄結構為:
-rw-r--r-- 1 ** ** 437 Sep 21 10:38 Dockerfile
drwxr-xr-x 2 ** ** 4096 Sep 20 13:59 lib
drwxr-xr-x 3 ** ** 4096 Sep 20 11:18 logs
-rwxrwxrwx 1 ** ** 3015 Sep 20 18:40 pom.xml
-rwxr-xr-x 1 ** ** 3102 Sep 20 18:54 pom.xml.undocker
drwxrwxrwx 3 ** ** 4096 Sep 20 11:18 src
-rw-r--r-- 1 ** ** 1028 Sep 20 10:27 start.sh
- 1
- 2
- 3
- 4
- 5
- 6
- 7
我的Dockerfile指定在根目錄下,當執行 mvn clean package docker:build後會生成一target檔案,檢視target目錄後預設生成docker資料夾,繼續檢視docker資料夾時可見,根目錄的所有內容都被copy到該資料夾下,在進行docker build的過程中也是在target/docker目錄下根據Dockerfile執行。
Dockerfile檔案內容如下,安裝了jdk,新增測試程式碼所需的一些庫:
From registry.test.com/base_image:centos6.6
ADD target/test-classes /data1/target/test-classes
ADD target/dockermaven/lib /data1/target/dockermaven/lib
ADD start.sh /data1/
ADD lib/jdk-1.8.0_77-2.el6.x86_64.rpm /jdk-1.8.0_77-2.el6.x86_64.rpm
RUN rpm -ivh /jdk-1.8.0_77-2.el6.x86_64.rpm
ENV JAVA_HOME /usr/local/jdk1.8.0_77
ENV PATH $PATH:$JAVA_HOME/bin
RUN chmod +x /data1/start.sh
WORKDIR /data1
CMD sh start.sh
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
構建命令
# maven打包並構建映象
mvn clean package -DskipTests=true docker:build
# maven打包構建映象並push到倉庫
mvn clean package docker:build -DpushImage
# maven打包構建映象,將指定tag的映象push到倉庫,該命令需使用
# <imageTags><imageTag>...</imageTag></imageTags>標籤
mvn clean package docker:build -DpushImageTag
<plugin>
<configuration>
...
<imageTags>
<imageTag>${project.version}</imageTag>
<imageTag>latest</imageTag>
</imageTags>
</configuration>
</plugin>
# 關於tags配置也可在命令列直接設定
mvn ... docker:build -DpushImageTags -DdockerImageTag=latest -DdockerImageTag=another-tag
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20