当前位置: 首页 > 知识库问答 >
问题:

Quarkus:尝试使用多级docker构建来缓存maven依赖项

姚骁
2023-03-14

我有一个简单的Quarkus应用程序,我尝试使用以下多级Dockerfile构建它。

FROM maven:3-jdk-8-slim AS build
WORKDIR /build
# Download Dependencies
COPY pom.xml .
RUN mvn dependency:go-offline

# Build App
COPY src/ /build/src/
RUN mvn -Dmaven.test.skip=true package -Dcheckstyle.skip

# Stage 2 : create the docker final image
FROM adoptopenjdk:8-jre-openj9 AS runtime
COPY --from=build /build/target/*-runner.jar /app/app.jar
COPY --from=build /build/target/lib/* /app/lib/

WORKDIR /app
RUN chgrp -R 0 /app &&\
    chmod g=u /app
USER 1001

EXPOSE 8080
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar"]

还有pom.xml

<?xml version="1.0"?>
<project
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
  xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.test</groupId>
  <artifactId>booking-mgr</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <compiler-plugin.version>3.8.1</compiler-plugin.version>
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <quarkus-plugin.version>1.1.1.Final</quarkus-plugin.version>
    <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
    <quarkus.platform.version>1.1.1.Final</quarkus.platform.version>
    <surefire-plugin.version>2.22.1</surefire-plugin.version>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>${quarkus.platform.artifact-id}</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.10</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-jsonb</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-openapi</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus-plugin.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemProperties>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
          </systemProperties>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemProperties>
                    <native.image.path>
                      ${project.build.directory}/${project.build.finalName}-runner
                    </native.image.path>
                  </systemProperties>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      <properties>
        <quarkus.package.type>native</quarkus.package.type>
      </properties>
    </profile>
  </profiles>
</project>

构建工作正常,它下载maven依赖项,然后它创建. jar并在最终容器中运行. jar。但是如果我更改源代码中的某些内容并保持pom.xml不变,依赖项会再次下载。似乎mvn依赖项:离线并没有下载所有依赖项。

有没有办法以这种方式加速docker构建?例如,我对Spring Boot做了同样的事情,那里一切都很好。

谢谢你的帮助。

共有3个答案

伏建修
2023-03-14

我发现< code>mvn package可以完成这项工作。现在我用:

COPY pom.xml .
RUN mvn --batch-mode \
        --quiet \
        --errors \
        dependency:go-offline \
        package

COPY src ./src
RUN mvn --batch-mode \
        --quiet \
        --errors \
        --define maven.test.skip=true \
        --define java.awt.headless=ture \
        clean package

看起来很奇怪,但没有错误。

扈沛
2023-03-14

简单地说,您可以将Dockerfile分成两部分,例如builder-base.dockerfilefinal.dockerfile。然后,创建一个目录builder-base并将pom.xml移动到builder-base

目录结构:

.
+-- builder-base
|   +-- pom.xml
|-- src
|-- builder-base.dockerfile
|-- final.dockerfile

在<code>final中。dockerfile是:

FROM java-builder AS build

# Build App
COPY src/ /build/src/
RUN mvn -Dmaven.test.skip=true package -Dcheckstyle.skip

# Stage 2 : create the docker final image
FROM adoptopenjdk:8-jre-openj9 AS runtime
COPY --from=build /build/target/*-runner.jar /app/app.jar
COPY --from=build /build/target/lib/* /app/lib/

WORKDIR /app
RUN chgrp -R 0 /app &&\
    chmod g=u /app
USER 1001

EXPOSE 8080
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar"]

首先,将此代码放入生成器库.docker 文件中

FROM maven:3-jdk-8-slim 
WORKDIR /build
# Download Dependencies
COPY pom.xml .
RUN mvn dependency:go-offline

因此,首先,您应该构建一个名为“java-builder”的映像

docker build -t java-builder -f builder.dockerfile ./builder-base

现在,您可以使用以下命令编译源代码:

docker build -t app -f final.dockerfile .

final.dockerfile中的基本映像是java-builder,如果不重新构建映像,您可以始终使用缓存创建docker最终映像。

孙永思
2023-03-14

您的pom.xml和src文件夹位于构建上下文(命令中的点)中。如果您更改src中的文件,那么您将更改构建上下文,从而使COPY缓存无效。

请参阅Docker build未使用缓存

 类似资料:
  • 我正在尝试在 Docker 容器中构建/部署Spring启动。 如您所见,我用第一个mvn命令缓存了所有的依赖项,这样我的代码应用程序中的每一个变化都不会触发新的大量依赖项下载。它适用于大多数依赖项,但仍有一些需要下载(即使缓存)。这是第二个mvn命令(包)的日志: (顺便说一句,(0 B在0 B / s)有点奇怪...只是一张支票? 如果我基于第一个maven命令之后的步骤启动一个容器(mvn依

  • 我想在Docker多阶段构建的构建阶段的一层中缓存Maven依赖项。 我的泊坞文件如下所示: ``` 我基于Docker多阶段构建博文(也可以在Github上获得)中提供的例子编写了这个Docker文件。 当我运行构建时,我看到的不是下载一次依赖项,然后由,而是通过两个步骤下载的依赖项。 有人让这个工作吗?我在这里做错了什么?

  • 我正在做一个有大约200MB依赖项的项目,我希望避免由于带宽有限而导致的无用上传。 当我推我的Dockerfile(我一会儿会附上)时,我总是有一个~200MB的上传,即使我没有碰pom.xml: 这个Dockerfile应该生成一个200MB的fatJAR,包括所有依赖项,这就是为什么每次都会发生~200MB的上传。我想要实现的是构建一个包含所有依赖项的层,并“告诉”打包阶段不要将依赖项JAR包

  • 我正在使用sh文件,其中包含所有专家配置,密钥,专家命令。当我运行容器时,它每次都会一次又一次地下载依赖项,它无法缓存依赖项。 下面是我的Dockerfile的外观: 下面是Test.sh文件 当我创建docker映像并运行容器时,每当我运行它时,它就会一次又一次地下载依赖项。

  • 我。 我有一个名为的模块,我希望将它的所有依赖项打包到一个JAR中。我不想每次都创建fat big jar,并将其与应用程序代码一起部署。我的应用程序jar的大小<1 MB,但依赖性>20 MB 在我的服务器上,我将运行我的应用程序,如下所示: 当我更改应用程序代码时,我只需要将部署到我的服务器,并且只有当我更改依赖项时才需要上传(这是非常罕见的)。 有很多关于如何使用java源代码构建fat j

  • 问题内容: 最近换用了Go 1.11版本,并正在尝试将我们的项目转换为使用新的模块系统。但是,我在缓存系统方面遇到了一个令人沮丧的问题(到目前为止,由于过去不相关的问题,我一直在使用它,但是模块不可以这样做)。 下面的命令日志基于使用我的系统使用Homebrew进行的全新升级到1.11(我通常使用gvm来安装和管理Go版本,但是为此交换到系统构建中以查看是否是gvm)。我将我的GOPATH设置为一