spring-boot-maven-plugin
自带的生成镜像功能超级慢。因为他要访问 Github 里面的东西,自己的电脑还好,CI 就扛不住了,在墙内的同事也扛不住了,而且那套逻辑也比较复杂灵活,不好掰出来里面的东西,这个一票否决。
使用这种方式不需要每个工程一个Dockerfile
,比如你想给所有项目的 Dockerfile 修改一些配置,此处修改一次,所有工程通吃。
这个一个 pom 工程,deploy 到私服上之后,下面的 Spring Boot 工程可以使用此 pom 作为 parent 代替 spring-boot-starter-parent 。如果你们已经有自定义的通用 pom,这个也可以被轻松整合进去。
利用了 Spring boot 2.3 引入的分层构建,每次重新构建镜像会复用上面的层,导致上传一次镜像到远程仓库之后,后面上传镜像都很快,从本来的要上传几十上百 M 缩减到现在的几 M 甚至 1M 不到(这个根据自己的工程体量)。Spring Boot 2.3 以下不可使用
保持清爽,不堆重复配置,按照约定大于配置原则,不像某些工程,一个 pom 光<build>
都几百行,其实大部分内容都是从网上上拷的,起不到作用。这个 pom 指定了很少的只是必须的内容,你可以轻轻松松的把其揉进已存的 pom 里面去。
按照<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>
![]() | 1 zzl22100048 2021-05-25 10:41:54 +08:00 ![]() 为啥不用 jib ? |
![]() | 2 qwerthhusn OP @zzl22100048 不知道啊,刚刚听,所以标题上写的“请大佬点评改进”。我来看看,也许能直接把我这钻木取火的方式给毙掉 |
3 BrbiwsFtd9zDGZqB 2021-05-25 11:18:16 +08:00 同 1 楼, 推荐 google 的 jib |
4 cslive 2021-05-25 11:46:11 +08:00 白嫖 Travis CI |
![]() | 5 zoharSoul 2021-05-25 12:08:10 +08:00 jib 了解一下 |
6 whitelee8080 2021-05-25 13:27:12 +08:00 同推荐 jib |
![]() | 7 balabalaXMX 2024-04-24 22:57:01 +08:00 想问一下楼主,jib 这个东西成熟吗? |