本文主要介绍如何通过 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 来替换该插件。
参考:https://github.com/spotify/docker-maven-plugin。