1. 本文環境
Maven:3.6.3(Maven配置參考)
SpringBoot version:2.3.4.RELEASE
Docker version: 19.03.11(Docker搭建參考)
JDK version:1.8.0_221(JDK搭建參考)
dev tools:IDEA(IDEA破解參考)
環境說明:本地跟docker不在同一環境,docker為單獨服務器。
2. 准備工作
通過 IDEA -> Spring Initializr 快速創建一個 SpringBoot 應用
填寫項目名、選擇 jdk 版本:
之后操作一路「藍色按鈕」默認即可。
創建后的項目 pom.xml 文件內容如下:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. Maven dockerfile 插件
將 SpringBoot 項目打包成 Docker 鏡像,其主要通過 Maven plugin 插件來進行構建。
在之前都是通過 docker-maven-plugin 插件進行打包,而現在已經升級出現了新的插件:
dockerfile-maven-plugin
接下來我們就是通過這個 plugin 插件進行操作。
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${docker.image.prefix}/${project.artifactId}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
參數說明:
-
repository:指定Docker鏡像的repo名字,要展示在docker images 中的。
-
tag:指定Docker鏡像的tag,不指定tag默認為latest
-
buildArgs:指定一個或多個變量,傳遞給Dockerfile,在Dockerfile中通過ARG指令進行引用。JAR_FILE 指定 jar 文件名。
另外,可以在execution中同時指定build和push目標。當運行mvn package時,會自動執行build目標,構建Docker鏡像。
DockerFile
DockerFile 文件需要放置在項目 pom.xm l同級目錄下,內容大致如下:
FROM java:8
EXPOSE 8080
ARG JAR_FILE
ADD target/${JAR_FILE} /niceyoo.jar
ENTRYPOINT ["java", "-jar","/niceyoo.jar"]
參數說明:
- FROM:基於java:8鏡像構建
- EXPOSE:監聽8080端口
- ARG:引用plugin中配置的 JAR_FILE 文件
- ADD:將當前 target 目錄下的 jar 放置在根目錄下,命名為 niceyoo.jar,推薦使用絕對路徑。
- ENTRYPOINT:執行命令 java -jar /niceyoo.jar
當前完整的 pom.xml:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<docker.image.prefix>10.211.55.4:5000</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${docker.image.prefix}/${project.artifactId}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
項目截圖:
4. 使用誤區
docker-maven-plugin 和 dockerfile-maven-plugin 使用誤區。
我們之前在使用 docker-maven-plugin 插件時,可以直接在本地就可以完成打包並推送鏡像至遠程倉庫,即 SpringBoot項目構建 docker 鏡像並推送到遠程倉庫:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<!--鏡像名稱-->
<imageName>10.211.55.4:5000/${project.artifactId}</imageName>
<!--指定dockerfile路徑-->
<!--<dockerDirectory>${project.basedir}/src/main/resources</dockerDirectory>-->
<!--指定標簽-->
<imageTags>
<imageTag>latest</imageTag>
</imageTags>
<!--遠程倉庫地址-->
<registryUrl>10.211.55.4:5000</registryUrl>
<pushImage>true</pushImage>
<!--基礎鏡像jdk1.8-->
<baseImage>java</baseImage>
<!--制作者提供本人信息-->
<maintainer>niceyoo apkdream@163.com</maintainer>
<!--切換到ROOT目錄-->
<workdir>/ROOT</workdir>
<cmd>["java","-version"]</cmd>
<entryPoint>["java","-jar","${project.build.finalName}.jar"]</entryPoint>
<!--指定遠程docker地址-->
<dockerHost>http://10.211.55.4:2375</dockerHost>
<!--這里是復制jar包到docker容器指定目錄配置-->
<resources>
<resource>
<targetPath>/ROOT</targetPath>
<!--指定需要復制的根目錄,${project.build.directory}表示target目錄-->
<directory>${project.build.directory}</directory>
<!--用於指定需要復制的文件,${project.build.finalName}.jar表示打包后的jar包文件-->
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
使用如上配置時,當執行 mvn package docker:build,即可完成打包至 docker 鏡像中。
但是,Dockerfile 就不一樣了,從我們開始編寫 Dockerfile 文件 FROM 命令開始,我們就發現,這個必須依賴於Docker,但問題就是,假設我本地跟 Docker 並不在一台機器上,那么我是沒法執行 dockerfile 的,如果在本地不安裝 docker 環境下,是沒法執行打包操作的,那么就可以將代碼拉取到 Docker 所在服務器,執行打包操作。
5. 項目打包
項目代碼結構:
執行 mvn clean package dockerfile:build -Dmaven.test.skip=true
執行 docker images 查看
至此,springboot 的鏡像就制作完成了。
6. 創建鏡像容器
上邊的步驟鏡像創建后,我們就可以直接來創建 springboot 容器來運行了。
docker run -d -p 8080:8080 10.211.55.4:5000/springboot-demo:0.0.1-SNAPSHOT
-
-d:表示在后台運行
-
-p:指定端口號,第一個8080為容器內部的端口號,第二個8080為外界訪問的端口號,將容器內的8080端口號映射到外部的8080端口號
-
10.211.55.4:5000/springboot-demo:0.0.1-SNAPSHOT:鏡像名+版本號。
如果覺得鏡像名稱過長的話,可以重命名:
docker tag 鏡像IMAGEID 新的名稱:版本號
以 10.211.55.4:5000/springboot-demo 為例:
docker tag 1815d40a66ae demo:latest
如果版本號不加的話,默認為 latest