zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Linux 下的类似Windows下Everything的搜索工具
    windows和linux环境下制作U盘启动盘
    程序调试手段之gdb, vxworks shell
    LeetCode 1021. Remove Outermost Parentheses (删除最外层的括号)
    LeetCode 1047. Remove All Adjacent Duplicates In String (删除字符串中的所有相邻重复项)
    LeetCode 844. Backspace String Compare (比较含退格的字符串)
    LeetCode 860. Lemonade Change (柠檬水找零)
    LeetCode 1221. Split a String in Balanced Strings (分割平衡字符串)
    LeetCode 1046. Last Stone Weight (最后一块石头的重量 )
    LeetCode 746. Min Cost Climbing Stairs (使用最小花费爬楼梯)
  • 原文地址:https://www.cnblogs.com/niceyoo/p/13796792.html
Copyright © 2011-2022 走看看