要通过 Maven 自动执行 Dockerfile 打包 Jar 并推送到镜像仓库,核心是使用 docker-maven-plugin (推荐 Spotify 官方插件,适配 Docker 原生构建流程)。以下是完整的 依赖配置 + 插件配置 + 执行命令,覆盖从 "打包 Jar" 到 "构建镜像 + 推送仓库" 的全自动化流程:
一、核心插件:Spotify Docker Maven Plugin
Spotify 的 docker-maven-plugin 是 Spring Boot 项目最常用的 Docker 集成插件,支持:
- 自动关联
package生命周期(打包 Jar 后自动构建镜像); - 读取项目 Dockerfile 构建镜像;
- 推送镜像到私有 / 公有仓库(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 Hub :
server.id可设为docker-hub,用户名 / 密码是 Docker Hub 的账号密码; - 若推送到 阿里云镜像仓库 :
server.id自定义,用户名是阿里云账号的 AccessKey ID,密码是 AccessKey Secret。
五、核心执行命令(自动化流程)
1. 本地构建镜像(无需推送)
执行 mvn package,会自动完成:
- 编译代码 → 打包 Jar 包(
target/应用名-版本号.jar); - 读取 Dockerfile → 构建 Docker 镜像;
- 镜像会被添加到本地 Docker 仓库(执行
docker images可查看)。
bash
运行
mvn clean package -DskipTests # -DskipTests 跳过测试(快速构建)
2. 构建镜像并推送到仓库
执行 mvn deploy,会自动完成:
- 编译 → 打包 → 构建镜像;
- 推送镜像到
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.host为tcp://远程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 镜像构建 + 仓库推送",核心步骤:
- 引入 Spring Boot 打包插件和 Docker 插件;
- 配置镜像名称、Dockerfile 路径、仓库认证;
- 编写配套 Dockerfile;
- 执行
mvn package(构建本地镜像)或mvn deploy(构建 + 推送)。