本文主要介绍如何通过 docker-maven-plugin 插件把 Java 服务构建成 docker 镜像;文中所使用到的软件版本:Docker 20.10.17、Java 1.8.0_341、SpringBoot 2.7.12、Maven 3.8.4、docker-maven-plugin 1.2.2。
1、docker-maven-plugin 插件信息
使用如下命令查看插件详细信息:
mvn help:describe -DartifactId=docker-maven-plugin -DgroupId=com.spotify -Dversion=1.2.2 -Ddetail
1.1、插件目标
该插件包含 5 个目标:
目标 | 说明 |
docker:build | 构建镜像 |
docker:help | 显示帮助信息 |
docker:push | 上传镜像 |
docker:removeImage | 删除镜像 |
docker:tag | 给镜像打标签 |
1.2、常用配置参数
1.2.1、docker:build 参数
参数 | 说明 |
baseImage | 基础镜像,如果设置了 dockerDirectory,忽略该参数 |
buildArgs | 定义 docker build 时的参数,可以在 Dockerfile 文件中使用这些参数 |
cmd | 定义容器默认的运行程序,如果设置了 dockerDirectory,忽略该参数 |
dockerDirectory | Dockerfie 文件所在目录(相对 pom.xml 的相对目录),如果没有配置该参数,将会根据 baseImage、entryPoint、cmd、maintainer 参数自动生成 Dockerfie |
dockerHost | docker 地址 |
entryPoint | 定义容器默认的运行程序,如果设置了 dockerDirectory,忽略该参数 |
imageName | 镜像名称 |
maintainer | 镜像维护者,如果设置了 dockerDirectory,忽略该参数 |
resources | 定义构建镜像所需的资源,这些资源会先 copy 到 Dockerfile 所在目录下 |
resources/resource | 一个资源配置 |
resources/resource/targetPath | 定义资源 copy 到的目标目录,该配置会在 Dockerfile 所在目录中创建对应参数值的目录 |
resources/resource/directory | 资源所在目录 |
resources/resource/include | 资源包含的文件 |
1.2.2、docker:removeImage 参数
参数 | 说明 |
dockerHost | docker 地址 |
imageName | 删除的镜像名称,包括 REPOSITORY 和 TAG |
imageTags | 与 imageName 中 REPOSITORY 一致, 其他需删除的 TAG |
1.2.3、docker:tag 参数
参数 | 说明 |
dockerHost | docker 地址 |
image | 镜像名称或镜像 id |
newName | 新的标签名称 |
1.2.4、docker:push 参数
参数 | 说明 |
serverId | 服务 id,对应 Maven settings.xml 中 servers/server 节点配置信息 |
registryUrl | 被推送的镜像仓库 |
imageName | 推送的镜像名称 |
2、docker-maven-plugin 插件使用
2.1、新建 SpringBoot 工程
<groupId>com.abc</groupId>
<artifactId>demo-general</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.12</version>
<relativePath />
</parent>
2.2、在 POM 中设置 build 信息
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<dockerHost>http://10.49.196.33:2375</dockerHost>
<baseImage>adoptopenjdk/openjdk8:latest</baseImage>
<imageName>${project.artifactId}:${project.version}</imageName>
<cmd>["java", "-jar", "/root/${project.build.finalName}.jar"]</cmd>
<resources>
<resource>
<targetPath>/root</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
执行如下命令生成镜像:
mvn package docker:build
先打包,然后生成镜像;镜像可在 docker 中查看:
2.3、使用 Dockerfile
2.3.1、新建 Dockerfile 文件
在项目下新建 docker 目录,并在该目录下新建 Dockerfile 文件:
Dockerfile 文件文件内容为:
From adoptopenjdk/openjdk8
ARG jarFile
COPY ${jarFile} /root/demo-general-1.0.0.jar
EXPOSE 9090
CMD ["java", "-jar", "/root/demo-general-1.0.0.jar"]
adoptopenjdk/openjdk8 为直接 pull 到本地的官方 jdk 镜像。
2.3.2、docker-maven-plugin 插件配置
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<dockerHost>http://10.49.196.33:2375</dockerHost>
<imageName>${project.artifactId}:${project.version}</imageName>
<dockerDirectory>docker</dockerDirectory>
<buildArgs>
<jarFile>${project.build.finalName}.jar</jarFile>
</buildArgs>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
执行如下命令生成镜像:
mvn package docker:build
2.4、绑定 Docker 命令到 Maven 生命周期阶段
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<dockerHost>http://10.49.196.33:2375</dockerHost>
<imageName>${project.artifactId}:${project.version}</imageName>
<dockerDirectory>docker</dockerDirectory>
<buildArgs>
<jarFile>${project.build.finalName}.jar</jarFile>
</buildArgs>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
<execution>
<id>tag-image</id>
<phase>package</phase>
<goals>
<goal>tag</goal>
</goals>
<configuration>
<image>${project.artifactId}:${project.version}</image>
<newName>10.49.196.34:18080/test/${project.artifactId}:${project.version}</newName>
</configuration>
</execution>
<execution>
<id>push-image</id>
<phase>verify</phase>
<goals>
<goal>push</goal>
</goals>
<configuration>
<serverId>my-harbor</serverId>
<registryUrl>http://10.49.196.34:18080</registryUrl>
<imageName>10.49.196.34:18080/test/${project.artifactId}:${project.version}</imageName>
</configuration>
</execution>
</executions>
</plugin>
上面的配置在打包阶段绑定了生成镜像及给镜像打标签的目标,执行 mvn package 命令后,到 docker 中查看镜像信息:
在 verify 阶段绑定了 push 镜像的目标,在 Maven settings.xml 中配置远程仓库 Harbor 的用户名密码:
<servers>
<server>
<id>my-harbor</id>
<username>admin</username>
<password>Harbor12345</password>
</server>
</servers>
执行 mvn verify 命令后,到 Harbor 中查看镜像信息:
3、替换插件
该插件在 Docker 的基础上引入了额外的抽象和配置,容易给用户带来困扰;官网建议使用 dockerfile-maven-plugin 来替换该插件。