分享一个 Spring Boot 工程打 Docker 镜像非常方便的 pom,你也 Docker 的距离就差一个好用的生成镜像的工具,求大佬点评改进! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
qwerthhusn
V2EX    程序员

分享一个 Spring Boot 工程打 Docker 镜像非常方便 pom,你也 Docker 的距离就差一个好用的生成镜像的工具,求大佬点评改进!

  •  
  •   qwerthhusn 2021-05-25 09:53:25 +08:00 2944 次点击
    这是一个创建于 1600 天前的主题,其中的信息可能已经有所发展或是发生改变。
    1. spring-boot-maven-plugin自带的生成镜像功能超级慢。因为他要访问 Github 里面的东西,自己的电脑还好,CI 就扛不住了,在墙内的同事也扛不住了,而且那套逻辑也比较复杂灵活,不好掰出来里面的东西,这个一票否决。

    2. 使用这种方式不需要每个工程一个Dockerfile,比如你想给所有项目的 Dockerfile 修改一些配置,此处修改一次,所有工程通吃。

    3. 这个一个 pom 工程,deploy 到私服上之后,下面的 Spring Boot 工程可以使用此 pom 作为 parent 代替 spring-boot-starter-parent 。如果你们已经有自定义的通用 pom,这个也可以被轻松整合进去。

    4. 利用了 Spring boot 2.3 引入的分层构建,每次重新构建镜像会复用上面的层,导致上传一次镜像到远程仓库之后,后面上传镜像都很快,从本来的要上传几十上百 M 缩减到现在的几 M 甚至 1M 不到(这个根据自己的工程体量)。Spring Boot 2.3 以下不可使用

    5. 保持清爽,不堆重复配置,按照约定大于配置原则,不像某些工程,一个 pom 光<build>都几百行,其实大部分内容都是从网上上拷的,起不到作用。这个 pom 指定了很少的只是必须的内容,你可以轻轻松松的把其揉进已存的 pom 里面去。

    6. 按照<profile>的 activation 机制自动识别 Spring Boot 工程,非 SpringBoot 工程也能正常把其作为 parent,而且会自动屏蔽掉镜像构建。

    <?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.example</groupId> <artifactId>spring-boot-docker-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <properties> <!-- TIPS: 默认使用的是 11 <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> --> <maven.compiler.release>11</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <version.spring-boot>2.4.5</version.spring-boot> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${version.spring-boot}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- TIPS: 添加其他依赖声明!此 pom 声明依赖版本,下面的工程不指定版本 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.4</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1.1-jre</version> </dependency> <dependency> <groupId>com.google.code.findbugs</groupId> <artifactId>annotations</artifactId> <version>3.0.1u2</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jetbrains</groupId> <artifactId>annotations</artifactId> <version>20.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${version.mapstruct}</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${version.mapstruct}</version> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <artifactId>maven-source-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> </plugins> <pluginManagement> <plugins> <!-- TIPS: 使用 JDK11,如果不指定 maven-compiler-plugin 版本的话,默认版本较低,会导致编译失败 如果使用 JDK8 或者以下,则此处声明可以删除,使用 Maven 默认指定的编译插件版本 --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> </plugin> </plugins> </pluginManagement> </build> <!-- TIPS --> <!-- 默认将构建镜像流程放到了 package 这个 phase,如果想放到 deploy 这个 phase,可自行修改 execution 下面的 phase mvn fr.jcgay.maven.plugins:buildplan-maven-plugin:list-phase 此 Maven 插件(不需要在<plugin>指定,直接运行 Maven 命令即可)可以帮助查看每个 phase 执行了哪个插件的哪些任务 --> <profiles> <profile> <id>spring-boot-package</id> <activation> <file> <!-- TIPS: 根据项目 Spring Boot 工程的特征,执行 profile 激活方式 比如此处去判断这个文件存在不存在来决定是否启用此 profile --> <exists>${basedir}/src/main/resources/config/application.properties</exists> </file> </activation> <build> <plugins> <plugin> <groupId>org.codehaus.gmaven</groupId> <artifactId>groovy-maven-plugin</artifactId> <version>2.1.1</version> <executions> <execution> <id>copy-Dockerfile</id> <phase>package</phase> <goals> <goal>execute</goal> </goals> </execution> </executions> <configuration> <!-- TIPS: 下面可以指定运行 JDK 版本号,示例使用的是 adoptopenjdk 11,JVM 启动参数 --> <source><![CDATA[ import java.nio.charset.StandardCharsets File dockerBuildDir = new File((File) basedir, "target/docker-build") dockerBuildDir.mkdirs() def dockerfile = """ FROM adoptopenjdk:11.0.11_9-jdk-hotspot as builder WORKDIR app/ ARG JAR_FILE COPY \${JAR_FILE} app.jar RUN java -Djarmode=layertools -jar app.jar extract FROM adoptopenjdk:11.0.11_9-jdk-hotspot WORKDIR /app/ COPY --from=builder /app/dependencies/ ./ COPY --from=builder /app/spring-boot-loader/ ./ COPY --from=builder /app/snapshot-dependencies/ ./ COPY --from=builder /app/application/ ./ ENTRYPOINT ["java", "-Dfile.encoding=utf-8", "-Duser.timezOne=Asia/Shanghai", "-Xms4g", "-Xmx4g", "-XX:+HeapDumpOnOutOfMemoryError", "org.springframework.boot.loader.JarLauncher"] """ fos = new FileOutputStream(new File(dockerBuildDir, "Dockerfile")) fos.write(dockerfile.getBytes(StandardCharsets.UTF_8)) fos.close() ]]></source> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${version.spring-boot}</version> <executions> <execution> <id>spring-boot-package</id> <phase>package</phase> <goals> <goal>repackage</goal> </goals> <configuration> <mainClass>${start-class}</mainClass> <outputDirectory>${project.build.directory}/docker-build/</outputDirectory> </configuration> </execution> </executions> </plugin> <plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.34.1</version> <executions> <execution> <id>docker-build-push</id> <phase>package</phase> <goals> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions> <configuration> <images> <image> <!-- TIPS:在 settings.xml 里面的<servers>下添加一个<server>指定镜像仓库的用户名和密码 CI 环境也可以通过指定 Java 变量参数来指定用户名密码 mvn -Ddocker.username=XXX -Ddocker.password=YYY clean package <server> <id>your.registry.domain</id> <username>用户名</username> <password>密码</password> </server> --> <!-- TIPS: 需要在工程下的<properties>下面指定一个 property,dockerImageGroupAndName 例如 abc/def --> <name>your.registry.domain/${dockerImageGroupAndName}</name> <build> <contextDir>${project.build.directory}/docker-build/</contextDir> <tags> <tag>${project.version}</tag> </tags> <args> <JAR_FILE>${project.build.finalName}.jar</JAR_FILE> </args> </build> </image> </images> </configuration> </plugin> </plugins> </build> </profile> </profiles> <!-- TIPS: 如需发布到 Maven 仓库,则指定下面的发布仓库地址 --> <distributionManagement> <repository> <id>xxx-release-deploy</id> <url>https://XXX/repository/maven-releases/</url> </repository> <snapshotRepository> <id>xxx-snapshot-deploy</id> <url>https://XXX/repository/maven-snapshots/</url> </snapshotRepository> </distributionManagement> </project> 
    7 条回复    2024-04-24 22:57:01 +08:00
    zzl22100048
        1
    zzl22100048  
       2021-05-25 10:41:54 +08:00   1
    为啥不用 jib ?
    qwerthhusn
        2
    qwerthhusn  
    OP
       2021-05-25 10:58:29 +08:00
    @zzl22100048 不知道啊,刚刚听,所以标题上写的“请大佬点评改进”。我来看看,也许能直接把我这钻木取火的方式给毙掉
    BrbiwsFtd9zDGZqB
        3
    BrbiwsFtd9zDGZqB  
       2021-05-25 11:18:16 +08:00
    同 1 楼, 推荐 google 的 jib
    cslive
        4
    cslive  
       2021-05-25 11:46:11 +08:00
    白嫖 Travis CI
    zoharSoul
        5
    zoharSoul  
       2021-05-25 12:08:10 +08:00
    jib 了解一下
    whitelee8080
        6
    whitelee8080  
       2021-05-25 13:27:12 +08:00
    同推荐 jib
    balabalaXMX
        7
    balabalaXMX  
       2024-04-24 22:57:01 +08:00
    想问一下楼主,jib 这个东西成熟吗?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     978 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 23:04 PVG 07:04 LAX 16:04 JFK 19:04
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86