maven自动构建到镜像仓库

要通过 Maven 自动执行 Dockerfile 打包 Jar 并推送到镜像仓库,核心是使用 docker-maven-plugin (推荐 Spotify 官方插件,适配 Docker 原生构建流程)。以下是完整的 依赖配置 + 插件配置 + 执行命令,覆盖从 "打包 Jar" 到 "构建镜像 + 推送仓库" 的全自动化流程:

一、核心插件:Spotify Docker Maven Plugin

Spotify 的 docker-maven-plugin 是 Spring Boot 项目最常用的 Docker 集成插件,支持:

  1. 自动关联 package 生命周期(打包 Jar 后自动构建镜像);
  2. 读取项目 Dockerfile 构建镜像;
  3. 推送镜像到私有 / 公有仓库(Docker Hub、Harbor、阿里云镜像仓库等)。

二、完整 Pom.xml 配置(关键部分)

1. 先引入插件依赖(在 <build><plugins> 中添加)

xml

复制代码
<build>
    <finalName>${project.artifactId}-${project.version}</finalName> <!-- 最终 Jar 包名:应用名-版本号 -->
    <plugins>
        <!-- 1. Spring Boot 打包插件(必须,先打 Jar 包) -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.7.18</version> <!-- 与 Spring Boot 版本一致 -->
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal> <!-- 打可执行 Jar 包 -->
                    </goals>
                </execution>
            </executions>
        </plugin>

        <!-- 2. Docker Maven 插件(核心,构建+推送镜像) -->
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.2.2</version> <!-- 稳定版本,适配大部分 Docker 环境 -->
            
            <!-- 绑定 Maven 生命周期:执行 mvn package 时自动构建镜像,执行 mvn docker:push 时推送镜像 -->
            <executions>
                <execution>
                    <id>build-image</id>
                    <phase>package</phase> <!-- 绑定到 package 阶段:打包 Jar 后自动构建镜像 -->
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
                <execution>
                    <id>push-image</id>
                    <phase>deploy</phase> <!-- 绑定到 deploy 阶段:执行 mvn deploy 时推送镜像 -->
                    <goals>
                        <goal>push</goal>
                    </goals>
                </execution>
            </executions>

            <!-- 插件配置:镜像名称、Dockerfile 路径、仓库地址等 -->
            <configuration>
                <!-- 镜像名称:仓库地址/项目名:版本号(例:私有仓库/应用名:1.0.0) -->
                <!-- 若推送到 Docker Hub:用户名/应用名:版本号(例:dockerhub用户名/my-app:1.0.0) -->
                <imageName>${docker.repo.url}/${project.artifactId}:${project.version}</imageName>
                
                <!-- Dockerfile 路径(默认在项目根目录,若在其他目录需指定,如 src/main/docker/Dockerfile) -->
                <dockerDirectory>${project.basedir}</dockerDirectory>
                
                <!-- 镜像标签(可选,可添加多个标签,如 latest) -->
                <imageTags>
                    <imageTag>${project.version}</imageTag>
                    <imageTag>latest</imageTag>
                </imageTags>
                
                <!-- 构建参数(可选,传递给 Dockerfile 的 ARG) -->
                <buildArgs>
                    <JAR_FILE>${project.build.finalName}.jar</JAR_FILE> <!-- 传递 Jar 包名给 Dockerfile -->
                </buildArgs>
                
                <!-- 镜像仓库认证信息(关键:推送镜像时需要) -->
                <serverId>${docker.repo.serverId}</serverId> <!-- 对应 settings.xml 中的 <server> 配置 ID -->
                
                <!-- Docker 守护进程地址(默认本地:unix:///var/run/docker.sock;远程 Docker 需指定 TCP 地址) -->
                <dockerHost>${docker.host}</dockerHost>
            </configuration>
        </plugin>
    </plugins>
</build>
2. 配置属性(在 <properties> 中添加,统一管理版本和路径)

xml

复制代码
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <docker.repo.url>harbor.example.com/my-project</docker.repo.url> <!-- 私有仓库地址(如 Harbor) -->
    <docker.repo.serverId>harbor-repo</docker.repo.serverId> <!-- 对应 settings.xml 的 server ID -->
    <docker.host>unix:///var/run/docker.sock</docker.host> <!-- 本地 Docker 地址(Windows 可能是 tcp://localhost:2375) -->
</properties>

三、配套的 Dockerfile(项目根目录)

插件会读取项目根目录的 Dockerfile 构建镜像,以下是 Spring Boot 通用 Dockerfile(与上面插件的 buildArgs 对应):

dockerfile

复制代码
# 基础镜像(Java 8,轻量版 alpine)
FROM openjdk:8-jre-alpine

# 维护者信息(可选)
LABEL maintainer="your-name <your-email@example.com>"

# 接收 Maven 传递的 JAR_FILE 参数(Jar 包名)
ARG JAR_FILE

# 创建工作目录
WORKDIR /app

# 复制 Jar 包到容器(从 Maven 构建目录 target/ 复制到容器 /app/,并重命名为 app.jar)
COPY target/${JAR_FILE} app.jar

# 暴露应用端口(与 Spring Boot 配置的 server.port 一致)
EXPOSE 8080

# 启动命令(Spring Boot 可执行 Jar 启动)
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

四、配置镜像仓库认证(settings.xml)

推送镜像到私有仓库(如 Harbor、阿里云镜像仓库)时,需要在 Maven 的 settings.xml 中配置仓库的用户名和密码(避免硬编码在 Pom 中)。

1. 找到 Maven 的 settings.xml 位置
  • 全局配置:${MAVEN_HOME}/conf/settings.xml(对所有项目生效);
  • 项目级配置:~/.m2/settings.xml(仅当前用户生效,推荐)。
2. 添加仓库认证配置(在 <servers> 中添加)

xml

复制代码
<servers>
    <!-- 镜像仓库认证:ID 必须与 Pom 中的 docker.repo.serverId 一致(例:harbor-repo) -->
    <server>
        <id>harbor-repo</id> <!-- 对应 Pom 中的 ${docker.repo.serverId} -->
        <username>your-repo-username</username> <!-- 仓库用户名(如 Harbor 账号) -->
        <password>your-repo-password</password> <!-- 仓库密码(如 Harbor 密码) -->
        <!-- 若密码是加密的,可配置 <privateKey> 和 <passphrase>(Maven 加密语法) -->
    </server>
</servers>
  • 若推送到 Docker Hubserver.id 可设为 docker-hub,用户名 / 密码是 Docker Hub 的账号密码;
  • 若推送到 阿里云镜像仓库server.id 自定义,用户名是阿里云账号的 AccessKey ID,密码是 AccessKey Secret。

五、核心执行命令(自动化流程)

1. 本地构建镜像(无需推送)

执行 mvn package,会自动完成:

  1. 编译代码 → 打包 Jar 包(target/应用名-版本号.jar);
  2. 读取 Dockerfile → 构建 Docker 镜像;
  3. 镜像会被添加到本地 Docker 仓库(执行 docker images 可查看)。

bash

运行

复制代码
mvn clean package -DskipTests  # -DskipTests 跳过测试(快速构建)
2. 构建镜像并推送到仓库

执行 mvn deploy,会自动完成:

  1. 编译 → 打包 → 构建镜像;
  2. 推送镜像到 docker.repo.url 配置的仓库(如 Harbor)。

bash

运行

复制代码
mvn clean deploy -DskipTests
3. 手动执行插件目标(灵活控制)
  • 手动构建镜像:mvn docker:build
  • 手动推送镜像:mvn docker:push
  • 构建并推送:mvn docker:build docker:push
  • 强制覆盖镜像:mvn docker:build -Ddocker.forceTags=true

六、关键注意事项

1. 环境依赖
  • 本地需安装 Docker,且 Docker 守护进程已启动(docker info 可验证);
  • Maven 版本需 ≥ 3.3.0(插件要求);
  • 若使用远程 Docker 服务(如服务器上的 Docker),需配置 docker.hosttcp://远程IP:2375(需开启远程 Docker 的 2375 端口,注意安全防护)。
2. Dockerfile 路径问题
  • 若 Dockerfile 不在项目根目录(如 src/main/docker/Dockerfile),需修改 Pom 中 dockerDirectory 为:

    xml

    复制代码
    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
3. 镜像名称规范
  • 镜像名称必须符合仓库要求:仓库地址/项目名:版本号(如 harbor.example.com/my-project/my-app:1.0.0);
  • 若省略仓库地址,镜像会被标记为 localhost:5000/项目名:版本号(仅本地可见,无法推送)。
4. 权限问题
  • Linux/Mac 下,若执行 mvn package 报错 Permission denied(无法访问 Docker 守护进程),需给当前用户添加 Docker 权限:

    bash

    运行

    复制代码
    sudo usermod -aG docker $USER  # 添加权限
    newgrp docker  # 生效权限(无需重启)

七、备选插件:Dockerfile Maven Plugin(推荐 Spring Boot 3.x)

若使用 Spring Boot 3.x 或需要更灵活的 Docker 构建(如多阶段构建),可替换为 dockerfile-maven-plugin(Spotify 后续维护的插件,更适配现代 Docker 特性),配置类似:

xml

复制代码
<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>dockerfile-maven-plugin</artifactId>
    <version>1.4.13</version>
    <executions>
        <execution>
            <id>default</id>
            <phase>package</phase>
            <goals>
                <goal>build</goal>
                <goal>push</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <repository>${docker.repo.url}/${project.artifactId}</repository>
        <tag>${project.version}</tag>
        <buildArgs>
            <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
        </buildArgs>
    </configuration>
</plugin>

总结

通过 docker-maven-plugin 可实现 "Maven 一条命令完成 Jar 打包 + Docker 镜像构建 + 仓库推送",核心步骤:

  1. 引入 Spring Boot 打包插件和 Docker 插件;
  2. 配置镜像名称、Dockerfile 路径、仓库认证;
  3. 编写配套 Dockerfile;
  4. 执行 mvn package(构建本地镜像)或 mvn deploy(构建 + 推送)。
相关推荐
czlczl200209251 小时前
SpringBoot手动配置:WebMvcConfigurer接口实现类的生效原理
java·spring boot·后端
程序员皮皮林1 小时前
SpringBoot + nmap4j 获取端口信息
java·spring boot·后端
小二·1 小时前
Spring框架入门:Spring 中注解支持详解
java·后端·spring
豐儀麟阁贵1 小时前
8.6运行时异常
java·开发语言
桃子叔叔1 小时前
Prompt Engineering完全指南:从基础到高阶技术实战
java·服务器·prompt
CRUD酱1 小时前
RabbitMQ是如何确保消息的可靠性的?
java·python·rabbitmq
百花~1 小时前
Spring IoC&DI~
java·后端·spring
独自破碎E1 小时前
矩阵区间更新TLE?试试二维差分
java·线性代数·矩阵
卷到起飞的数分1 小时前
20.Spring Boot原理2
java·spring boot·后端