1. 程式人生 > >maven構建docker映象三部曲之二:編碼和構建映象

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,瀏覽器訪問地址是:

https://github.com/zq2599/blog_demos,這裡面有多個工程,本次實戰用到的是mavendockerplugindemo,如下圖紅框所示:
這裡寫圖片描述

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來構建了;

  1. 在windows電腦上,我將工程壓縮成mavendockerplugindemo.zip檔案,存放在D:\blog目錄下;
  2. 在linux虛擬機器新建目錄/usr/local/work
  3. 在linux虛擬機器執行命令apt-get install -y unzip,安裝解壓工具;
  4. 複製檔案,推薦使用SecureCRT的SFTP工具,先用SecureCRT登入虛擬機器,再建立SFTP連線,如下圖紅框所示:
    這裡寫圖片描述
  5. 在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外掛的推送能力,將本地映象推送到私服,這樣就能將專案編譯構建、映象構建、映象推送等環節整合在一次構建中完成;