SpringBoot打包成Docker镜像

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

博客地址:https://www.cnblogs.com/niceyoo

原文地址:https://www.cnblogs.com/niceyoo/p/13796792.html