maven構建docker映象三部曲之二:編碼和構建映象
在《maven構建docker映象三部曲之一:準備環境》中,我們在vmware上準備好了ubuntu16虛擬機器,並且裝好了docker、jdk8、maven等必備工具,現在我們來開發一個java web工程,再用docker-maven-plugin外掛來構建本地的docker映象;
web工程
我們採用spring boot的web工程作為實戰的應用,這樣的好處是簡單快速的建立和部署專案,這只是個最簡單的、基於maven構建的spring boot web工程,原始碼我已經上傳到github上,地址是:[email protected]:zq2599/blog_demos.git,瀏覽器訪問地址是:
java程式碼
mavendockerplugindemo工程的程式碼非常簡單,只有一個controller,如下圖:
pom.xml
整個工程的pom.xml也很簡單,依賴spring-boot-starter-web,構建的時候使用spring-boot-maven-plugin外掛,如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bolingcavalry</groupId>
<artifactId>mavendockerplugindemo</artifactId >
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mavendockerplugindemo</name>
<description>maven docker plugin demo</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
正常情況下,工程執行起來後在瀏覽器訪問http://x.x.x.x:8080,就會顯示如下資訊(x.x.x.x代表執行工程的機器ip):
將工程複製到linux虛擬機器上
在上一章在《maven構建docker映象三部曲之一:準備環境》我們將虛擬機器的docker、jdk、maven等環境都準備好了,現在將spring boot工程放到虛擬機器上,然後就能用maven來構建了;
- 在windows電腦上,我將工程壓縮成mavendockerplugindemo.zip檔案,存放在D:\blog目錄下;
- 在linux虛擬機器新建目錄/usr/local/work;
- 在linux虛擬機器執行命令apt-get install -y unzip,安裝解壓工具;
- 複製檔案,推薦使用SecureCRT的SFTP工具,先用SecureCRT登入虛擬機器,再建立SFTP連線,如下圖紅框所示:
- 在SFTP視窗執行以下命令:
#進入本機的d:/blog/目錄
lcd d:/blog/
#進入linux的/usr/local/work/目錄
cd /usr/local/work/
#將本機d:/blog/目錄下的mavendockerplugindemo.zip檔案上傳到linux的/usr/local/work/目錄下
put mavendockerplugindemo.zip
這樣就能將檔案從windows電腦傳到linux虛擬機器上,如果想把linux虛擬機器上的xxx檔案下載到windows電腦,執行get xxx命令即可;
5. 關閉SFTP視窗,在ssh視窗進入/usr/local/work/,執行命令unzip mavendockerplugindemo.zip將工程解壓縮;
6. 請注意:接下來的操作都在linux虛擬機器上進行;;
映象構建方式
docker-maven-plugin外掛構建docker映象有兩種方式:
1. 指定引數,由docker-maven-plugin外掛根據這些引數來製作映象;
2. 指定Dockerfile,這和我們用docker build命令來構建映象的過程一樣,不過docker-maven-plugin幫我們把工程構建和映象構建兩件事串起來了;
接下來我們將上述兩種方式都實踐一下;
第一種構建方式:通過引數構建
在mavendockerplugindemo工程目錄下新建檔案pom_1_by_param.xml,內容和pom.xml一樣,然後我們再去<plugins>節點新增以下內容,放在原有的<plugin>節點後面,如下所示:
<plugins>
<!--這是原有的spring boot外掛-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--新增的docker maven外掛-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.12</version>
<!--docker映象相關的配置資訊-->
<configuration>
<!--映象名,這裡用工程名-->
<imageName>${project.artifactId}</imageName>
<!--TAG,這裡用工程版本號-->
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
<!--映象的FROM,使用java官方映象-->
<baseImage>java:8u111-jdk</baseImage>
<!--該映象的容器啟動後,直接執行spring boot工程-->
<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>
上面的每個引數都已加了註釋,就不多說了,在此檔案所在目錄執行以下命令,指定pom_1_by_param.xml作為pom檔案執行maven構建:
mvn -f pom_1_by_param.xml clean package -DskipTests docker:build
執行成功後輸出以下資訊:
[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ mavendockerplugindemo ---
[INFO] Building jar: /usr/local/work/mavendockerplugindemo/target/mavendockerplugindemo-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:1.5.9.RELEASE:repackage (default) @ mavendockerplugindemo ---
[INFO]
[INFO] --- docker-maven-plugin:0.4.12:build (default-cli) @ mavendockerplugindemo ---
[INFO] Copying /usr/local/work/mavendockerplugindemo/target/mavendockerplugindemo-0.0.1-SNAPSHOT.jar -> /usr/local/work/mavendockerplugindemo/target/docker/mavendockerplugindemo-0.0.1-SNAPSHOT.jar
[INFO] Building image mavendockerplugindemo
Step 1/3 : FROM java:8u111-jdk
---> d23bdf5b1b1b
Step 2/3 : ADD /mavendockerplugindemo-0.0.1-SNAPSHOT.jar //
---> 74f201b46c92
Removing intermediate container cbc9e456d139
Step 3/3 : ENTRYPOINT java -jar /mavendockerplugindemo-0.0.1-SNAPSHOT.jar
---> Running in 256a09be033d
---> ad342e51021e
Removing intermediate container 256a09be033d
Successfully built ad342e51021e
[INFO] Built mavendockerplugindemo
[INFO] Tagging mavendockerplugindemo with 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.617 s
[INFO] Finished at: 2017-12-23T00:00:06-08:00
[INFO] Final Memory: 35M/84M
[INFO] ------------------------------------------------------------------------
執行docker images命令可以看到如下資訊,新的映象已經建立好了:
REPOSITORY TAG IMAGE ID CREATED SIZE
mavendockerplugindemo 0.0.1-SNAPSHOT ad342e51021e 10 minutes ago 658 MB
mavendockerplugindemo latest ad342e51021e 10 minutes ago 658 MB
java 8u111-jdk d23bdf5b1b1b 11 months ago 643 MB
為什麼會有兩個名為mavendockerplugindemo的映象呢?看一下maven的構建日誌,有下面這麼一句:
[INFO] Tagging mavendockerplugindemo with 0.0.1-SNAPSHOT
原來是以構建好的latest映象的基礎,按照我們的配置上做了一次TAG操作,本身映象是同一個(IMAGE ID相同);
驗證第一種方式構建的映象
執行以下命令,使用剛剛構建的映象建立一個容器:
docker run --name demo001 -p 8080:8080 mavendockerplugindemo:0.0.1-SNAPSHOT
啟動資訊如下所示:
我這裡linux虛擬機器的IP是192.168.119.155,所以在windows上開啟瀏覽器,輸入地址:192.168.119.155:8080,看到如下效果,web專案正常啟動:
第二種構建方式:指定Dockerfile
這種方式要我們自己寫Dockerfile,好處是可以按照自己的需要在Dockerfile中新增更多內容,而不像第一種方式那樣只能按照外掛的引數規則來配置;
先把之前的容器停掉,現在虛擬機器的控制檯應該還是剛剛我們啟動的容器的輸出,鍵入“Ctrl + c”退出此容器,這樣才會解除8080埠的佔用;
在mavendockerplugindemo工程目錄下新建檔案pom_2_by_dockerfile.xml,內容和pom.xml一樣,然後我們再去<plugins>節點新增以下內容,放在原有的<plugin>節點後面,如下所示:
<!--新增的docker maven外掛-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.12</version>
<!--docker映象相關的配置資訊-->
<configuration>
<!--映象名,這裡用工程名-->
<imageName>${project.artifactId}</imageName>
<!--Dockerfile檔案所在目錄--> <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<!--TAG,這裡用工程版本號-->
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
<!--構建映象的配置資訊-->
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
和之前的pom_1_by_param.xml相比有如下變動:
1. 新增<dockerDirectory>節點用來表示自定義Dockerfile檔案的位置;
2. <baseImage>和<entryPoint>節點用不上了,在此刪掉;
- 為了和第一種構建結果區分開,把pom_2_by_dockerfile.xml中定義的工程版本號從0.0.1-SNAPSHOT改為0.0.2-SNAPSHOT,如下所示:
<groupId>com.bolingcavalry</groupId>
<artifactId>mavendockerplugindemo</artifactId>
<version>0.0.2-SNAPSHOT</version>
<packaging>jar</packaging>
- 在工程的src/main/docker/目錄下新建Dockerfile檔案,如下圖:
Dockerfile的內容如下,就是將工程構建完畢後的jar包複製到home目錄,然後構建映象:
ENV ARTIFACTID mavendockerplugindemo
ENV ARTIFACTVERSION 0.0.2-SNAPSHOT
ENV HOME_PATH /home
ADD /$ARTIFACTID-$ARTIFACTVERSION.jar $HOME_PATH/mavendockerplugindemo.jar
WORKDIR $HOME_PATH
ENTRYPOINT ["java","-jar","mavendockerplugindemo.jar"]
- 可以開始構建了,在pom_2_by_dockerfile.xml所在目錄執行以下命令:
mvn -f pom_2_by_dockerfile.xml clean package -DskipTests docker:build
會看到如下輸出資訊:
[INFO] --- docker-maven-plugin:0.4.12:build (default-cli) @ mavendockerplugindemo ---
[INFO] Copying /usr/local/work/mavendockerplugindemo/target/mavendockerplugindemo-0.0.2-SNAPSHOT.jar -> /usr/local/work/mavendockerplugindemo/target/docker/mavendockerplugindemo-0.0.2-SNAPSHOT.jar
[INFO] Copying /usr/local/work/mavendockerplugindemo/src/main/docker/Dockerfile -> /usr/local/work/mavendockerplugindemo/target/docker/Dockerfile
[INFO] Building image mavendockerplugindemo
Step 1/7 : FROM java:8u111-jdk
---> d23bdf5b1b1b
Step 2/7 : ENV ARTIFACTID mavendockerplugindemo
---> Using cache
---> bf895524c43e
Step 3/7 : ENV ARTIFACTVERSION 0.0.2-SNAPSHOT
---> Using cache
---> 1837d1412fae
Step 4/7 : ENV HOME_PATH /home
---> Using cache
---> 6220811f7777
Step 5/7 : ADD /$ARTIFACTID-$ARTIFACTVERSION.jar $HOME_PATH/mavendockerplugindemo.jar
---> 9f174f1e3c65
Removing intermediate container 9a8bc49917f4
Step 6/7 : WORKDIR $HOME_PATH
---> a34f05e5a272
Removing intermediate container 4bd7c136607d
Step 7/7 : ENTRYPOINT java -jar mavendockerplugindemo.jar
---> Running in 3122df8b7121
---> 5914eaeb88ab
Removing intermediate container 3122df8b7121
Successfully built 5914eaeb88ab
[INFO] Built mavendockerplugindemo
[INFO] Tagging mavendockerplugindemo with 0.0.2-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.848 s
[INFO] Finished at: 2017-12-23T02:42:11-08:00
[INFO] Final Memory: 35M/84M
[INFO] ------------------------------------------------------------------------
輸入docker images命令,看到的資訊如下,映象已經在本地了:
REPOSITORY TAG IMAGE ID CREATED SIZE
mavendockerplugindemo 0.0.2-SNAPSHOT 5914eaeb88ab About a minute ago 658 MB
mavendockerplugindemo latest 5914eaeb88ab About a minute ago 658 MB
mavendockerplugindemo 0.0.1-SNAPSHOT ad342e51021e 2 hours ago 658 MB
驗證第二種方式構建的映象
執行以下命令,使用剛剛構建的映象建立一個容器:
docker run --name demo002 -p 8080:8080 mavendockerplugindemo:0.0.2-SNAPSHOT
再去windows的瀏覽器上訪問http://192.168.119.155:8080/,可以看到和之前一樣的資訊,如果您不放心,也可以自己修改工程的controller原始碼,再構建驗證是否生效;
至此,我們通過兩種方式構建本地docker映象的實戰就結束了,但映象停留在本地,只能手工push到公有或者私有倉庫才能給其他人使用,在下一章我們就來體驗docker-maven-plugin外掛的推送能力,將本地映象推送到私服,這樣就能將專案編譯構建、映象構建、映象推送等環節整合在一次構建中完成;