从 spring maven 项目为arm64平台构建Docker镜像

发布于 2025-01-16 16:57:13 字数 8517 浏览 0 评论 0原文

我正在学习 Spring 课程,并且我有一个从 Spring Initializr 构建的 Maven 应用程序(从课程资源下载)。我可以使用 mvn spring-boot:build-image 构建本地 Docker 映像(项目中没有 Dockerfile)。默认情况下,Docker 映像构建为 linux/amd64,但我正在使用 M1 Apple Silicon 芯片 (arm64)。我一直在寻找很多解决方法,但没有成功。最后,我发现也许可以添加一个 Dockerfile 并指定相应的平台来构建镜像。

我的目标是为arm64架构构建一个docker镜像。

因此,我创建了一个Dockerfile:

FROM --platform=linux/arm64 maven:3.8.4-jdk-11 AS build
COPY src /home/path_to_app/src
COPY pom.xml /home/path_to_app
RUN mvn -f /home/path_to_app/pom.xml spring-boot:build-image -DskipTests 

我的项目结构是:

标准 maven 结构

在终端中,在同一个 pom.xml 目录中,我运行: docker buildx build --platform linux/arm64 --tag; .

记录成功,直到 =>Building image 'docker.io/myusername/myimage:mytag', 然后发生异常并且构建失败。

#8 125.7 [INFO] 
#8 125.7 [INFO] <<< spring-boot-maven-plugin:2.5.0:build-image (default-cli) < package @ currency-exchange-service <<<
#8 125.7 [INFO] 
#8 125.7 [INFO] 
#8 125.7 [INFO] --- spring-boot-maven-plugin:2.5.0:build-image (default-cli) @ currency-exchange-service ---
#8 125.8 [INFO] Building image 'docker.io/myname/myimage:0.0.1-SNAPSHOT'
#8 125.8 [INFO]
#8 125.8 [INFO] I/O exception (java.io.IOException) caught when processing request to {}->docker://localhost:2376: com.sun.jna.LastErrorException: [2] No such file or directory
#8 125.8 [INFO] Retrying request to {}->docker://localhost:2376
#8 125.8 [INFO] I/O exception (java.io.IOException) caught when processing request to {}->docker://localhost:2376: com.sun.jna.LastErrorException: [2] No such file or directory
#8 125.8 [INFO] Retrying request to {}->docker://localhost:2376
#8 125.8 [INFO] I/O exception (java.io.IOException) caught when processing request to {}->docker://localhost:2376: com.sun.jna.LastErrorException: [2] No such file or directory
#8 125.8 [INFO] Retrying request to {}->docker://localhost:2376
#8 125.9 [INFO] ------------------------------------------------------------------------
#8 125.9 [INFO] BUILD FAILURE
#8 125.9 [INFO] ------------------------------------------------------------------------
#8 125.9 [INFO] Total time:  02:04 min
#8 125.9 [INFO] Finished at: 2022-03-22T21:08:20Z
#8 125.9 [INFO] ------------------------------------------------------------------------
#8 125.9 [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.5.0:build-image 
(default-cli) on project currency-exchange-service: Execution default-cli 
of goal org.springframework.boot:spring-boot-maven-plugin:2.5.0:build-image 
failed: Connection to the Docker daemon at 'localhost' failed with error "[2] 
No such file or directory"; ensure the Docker daemon is running and accessible:
com.sun.jna.LastErrorException: [2] No such file or directory -> [Help 1]

我的 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.5.0</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.somename.microservices</groupId>
    <artifactId>mymicroservice-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mymicroservice-service-docker</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>2020.0.2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-spring-boot2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <name>myusername/myprefix${project.artifactId}:${project.version}</name>
                    </image>
                    <pullPolicy>IF_NOT_PRESENT</pullPolicy>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

</project>

我的 docker 守护进程正在运行。无法弄清楚为什么它尝试到达 localhost:2376 (我的项目中没有这样的端口)。 我的 DOCKER_HOST 设置为 unix:///var/run/docker.sock 并且工作正常。 尝试添加到 daemon.json:

{
"hosts": ["tcp://127.0.0.1:2376", "unix:///var/run/docker.sock"]
}

但 docker daemon 无法初始化(绑定错误,端口已在使用中)

我不知道 com.sun.jna.LastErrorException 来自哪里。

我怀疑可能需要 Docker in docker (dind) ,但我不知道如何在我的 Dockerfile 中设置它。或者可能是端口绑定配置。

预先感谢您的帮助!

注意:我只想在本地构建映像。我不想推送到 docker 注册表。我不希望构建过程中有任何其他阶段。

I'm in a Spring course, and I have a maven application (downloaded from the course resources) built from spring initializr. I can build a local Docker image with mvn spring-boot:build-image (no Dockerfile in the project). By default a Docker image is built as linux/amd64, but I am working with a M1 Apple Silicon chip (arm64). I've been looking many workarounds but with no success. Lastly, I found that maybe adding a Dockerfile and specifying the platform it would build the image accordingly.

My goal is to build a docker image for arm64 architecture.

So, I created a Dockerfile:

FROM --platform=linux/arm64 maven:3.8.4-jdk-11 AS build
COPY src /home/path_to_app/src
COPY pom.xml /home/path_to_app
RUN mvn -f /home/path_to_app/pom.xml spring-boot:build-image -DskipTests 

My project structure is:

standard maven structure

In terminal, at same pom.xml directory I run: docker buildx build --platform linux/arm64 --tag <mytag> .

Logs successful until =>Building image 'docker.io/myusername/myimage:mytag',
then an exception occurs and build fails.

#8 125.7 [INFO] 
#8 125.7 [INFO] <<< spring-boot-maven-plugin:2.5.0:build-image (default-cli) < package @ currency-exchange-service <<<
#8 125.7 [INFO] 
#8 125.7 [INFO] 
#8 125.7 [INFO] --- spring-boot-maven-plugin:2.5.0:build-image (default-cli) @ currency-exchange-service ---
#8 125.8 [INFO] Building image 'docker.io/myname/myimage:0.0.1-SNAPSHOT'
#8 125.8 [INFO]
#8 125.8 [INFO] I/O exception (java.io.IOException) caught when processing request to {}->docker://localhost:2376: com.sun.jna.LastErrorException: [2] No such file or directory
#8 125.8 [INFO] Retrying request to {}->docker://localhost:2376
#8 125.8 [INFO] I/O exception (java.io.IOException) caught when processing request to {}->docker://localhost:2376: com.sun.jna.LastErrorException: [2] No such file or directory
#8 125.8 [INFO] Retrying request to {}->docker://localhost:2376
#8 125.8 [INFO] I/O exception (java.io.IOException) caught when processing request to {}->docker://localhost:2376: com.sun.jna.LastErrorException: [2] No such file or directory
#8 125.8 [INFO] Retrying request to {}->docker://localhost:2376
#8 125.9 [INFO] ------------------------------------------------------------------------
#8 125.9 [INFO] BUILD FAILURE
#8 125.9 [INFO] ------------------------------------------------------------------------
#8 125.9 [INFO] Total time:  02:04 min
#8 125.9 [INFO] Finished at: 2022-03-22T21:08:20Z
#8 125.9 [INFO] ------------------------------------------------------------------------
#8 125.9 [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.5.0:build-image 
(default-cli) on project currency-exchange-service: Execution default-cli 
of goal org.springframework.boot:spring-boot-maven-plugin:2.5.0:build-image 
failed: Connection to the Docker daemon at 'localhost' failed with error "[2] 
No such file or directory"; ensure the Docker daemon is running and accessible:
com.sun.jna.LastErrorException: [2] No such file or directory -> [Help 1]

My 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.5.0</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.somename.microservices</groupId>
    <artifactId>mymicroservice-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mymicroservice-service-docker</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>2020.0.2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-spring-boot2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <name>myusername/myprefix${project.artifactId}:${project.version}</name>
                    </image>
                    <pullPolicy>IF_NOT_PRESENT</pullPolicy>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

</project>

My docker daemon is running. Can't figure out why it tries to reach localhost:2376 (There is no such port in my project).
My DOCKER_HOST is set to unix:///var/run/docker.sock and works fine.
Tried to add to daemon.json:

{
"hosts": ["tcp://127.0.0.1:2376", "unix:///var/run/docker.sock"]
}

but docker daemon can't initialize (binding error, port already in use)

I don't know where does com.sun.jna.LastErrorException come from.

I suspect that maybe Docker in docker (dind) is needed, but I don't know how to set it up in my Dockerfile. Or maybe a port binding configuration.

Thank in advance for any help!!!

Note: I just want to build the image locally. I don't wish pushing to docker registry. I don't want any other stages in the build process.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不念旧人 2025-01-23 16:57:13

目前无法使用 mvn spring-boot:build-image 构建基于 ARM 的映像,因为 Spring Boot 集成的 Cloud Native Buildpacks 构建器不支持此功能。这是 Paketo buildpacks 2022 路线图可能关注的项目之一,你可以投票。

CNB 记录了一个解决方法,但是设置和运行并不简单。

RUN mvn -f /home/path_to_app/pom.xml spring-boot:build-image -DskipTests

你需要 Docker-in-Docker 来完成这样的工作,因为 CNB 构建器会处理在 Docker 容器内运行需要与 Docker 守护进程对话。无论如何,由于上述原因,这将不允许您构建 ARM 映像。

Building an ARM-based image is not currently possible with mvn spring-boot:build-image, because the Cloud Native Buildpacks builders that Spring Boot integrates with do not support this. This is one of the possible items of focus on the Paketo buildpacks 2022 roadmap, which you can cast votes for.

CNB documents a work-around for this, but it's not simple to set up and run.

RUN mvn -f /home/path_to_app/pom.xml spring-boot:build-image -DskipTests

You would need Docker-in-Docker to make something like this work, since the CNB builder processes that would run inside the Docker container need to talk to the Docker daemon. Regardless, this would not allow you to build an ARM image for the reasons stated above.

落花浅忆 2025-01-23 16:57:13

您可以尝试进行多架构构建或仅进行 arm64 构建。看看 Fabric8 的 docker-maven-plugin

You can try doing a multi-architecture build or just an arm64 build. Have a look at the docker-maven-plugin by fabric8

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文