Docker系列教程12-使用Maven插件构建Docker镜像
我们知道,Maven是一个强大的项目管理与构建工具。如果可以使用Maven构建Docker镜像,那么我们的工作就能得到进一步的简化。
经过调研,以下几款Maven的Docker插件进入笔者视野,如表13-1所示。
插件名称 |
官方地址 |
---|---|
docker-maven-plugin |
https://github.com/spotify/docker-maven-plugin |
docker-maven-plugin |
https://github.com/fabric8io/docker-maven-plugin |
docker-maven-plugin |
https://github.com/bibryam/docker-maven-plugin |
表13-1 Maven的Docker插件列表
笔者从各项目的功能性、文档易用性、更新频率、社区活跃度、Stars等几个纬度考虑,选用了第一款。这是一款由Spotify公司开发的Maven插件。
下面我们来详细探讨如何使用Maven插件构建Docker镜像。
快速入门
以项目 microservice-discovery-eureka
为例。
(1) 在pom.xml中添加Maven的Docker插件。
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>itmuch/microservice-discovery-eureka:0.0.1</imageName>
<baseImage>java</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
简要说明一下插件的配置:
① imageName:用于指定镜像名称,其中itmuch是仓库名称,microservice-discovery-eureka是镜像名称,0.0.1是标签名称。
② baseImage:用于指定基础镜像,类似于Dockerfile中的FROM指令。
③ entrypoint:类似于Dockerfile的ENTRYPOINT指令。
④ resources.resource.directory:用于指定需要复制的根目录,${project.build.directory}表示target目录。
⑤ resources.resource.include:用于指定需要复制的文件。${project.build.finalName}.jar指的是打包后的jar包文件。
(2) 执行以下命令,构建Docker镜像。
mvn clean package docker:build
我们会发现终端输出类似于如下的内容:
[INFO] Building image itmuch/microservice-discovery-eureka:0.0.1
Step 1 : FROM java
---> 861e95c114d6
Step 2 : ADD /microservice-discovery-eureka-0.0.1-SNAPSHOT.jar //
---> 035a03f5b389
Removing intermediate container 2b0e70056f1d
Step 3 : ENTRYPOINT java -jar /microservice-discovery-eureka-0.0.1-SNAPSHOT.jar
---> Running in a0149704b949
---> eb96ca1402aa
Removing intermediate container a0149704b949
Successfully built eb96ca1402aa
由以上日志可知,我们已成功构建了一个Docker镜像。
(3)执行 docker images
命令,即可查看刚刚构建的镜像。
REPOSITORY TAG IMAGE ID CREATED SIZE
itmuch/microservice-discovery-eureka 0.0.1 eb96ca1402aa 39 seconds ago 685 MB
(4) 启动镜像
docker run -d -p 8761:8761 itmuch/microservice-discovery-eureka:0.0.1
我们会发现该Docker镜像会很快地启动
(5) 访问测试
访问http://Docker宿主机IP:8761 ,能够看到Eureka Server的首页。
插件读取Dockerfile进行构建
之前的示例,我们直接在pom.xml中设置了一些构建的参数。很多场景下,我们希望使用Dockerfile更精确、有可读性地构建镜像。
(1) 首先我们在 /microservice-discovery-eureka/src/main/docker
目录下,新建一个Dockerfile文件,例如:
FROM java:8
VOLUME /tmp
ADD microservice-discovery-eureka-0.0.1-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
EXPOSE 9000
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
(2) 修改pom.xml
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>itmuch/microservice-discovery-eureka:0.0.2</imageName>
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
可以看到,我们不再指定baseImage和entrypoint,而是使用dockerDirectory指定Dockerfile所在的路径。这样,我们就可以使用Dockerfile构建Docker镜像了。
将插件绑定在某个phase执行
很多场景下,我们有这样的需求,执行例如 mvn cleanpackage
时,插件就自动为我们构建Docker镜像。要想实现这点,我们只需将插件的goal绑定在某个phase即可。
phase和goal可以这样理解:maven命令格式是: mvn phase:goal
,例如 mvnpackagedocker:build
。那么,package和docker都是phase,build则是goal 。示例:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<imageName>itmuch/microservice-discovery-eureka:0.0.3</imageName>
<baseImage>java</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
由配置可知,我们只需添加如下配置:
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
就可将插件绑定在package这个phase上。也就是说,用户只需执行 mvnpackage
,就会自动执行 mvn docker:build
。当然,读者也可按照需求,将插件绑定到其他的phase。
推送镜像
前文我们使用 docker push
命令实现了镜像的推送,我们也可使用Maven插件推送镜像。我们不妨使用Maven插件推送一个Docker镜像到Docker Hub。
(1) 修改Maven的全局配置文件setttings.xml,在其中添加以下内容,配置Docker Hub的用户信息。
<server>
<id>docker-hub</id>
<username>你的DockerHub用户名</username>
<password>你的DockerHub密码</password>
<configuration>
<email>你的DockerHub邮箱</email>
</configuration>
</server>
(2) 修改pom.xml,示例:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>itmuch/microservice-discovery-eureka:0.0.4</imageName>
<baseImage>java</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<!-- 与maven配置文件settings.xml中配置的server.id一致,用于推送镜像 -->
<serverId>docker-hub</serverId>
</configuration>
</plugin>
如上,添加serverId段落,并引用settings.xml中的server的id即可。
(3) 执行以下命令,添加pushImage的标识,表示推送镜像。
mvn clean package docker:build -DpushImage
经过一段时间的等待,我们会发现Docker镜像已经被push到Docker Hub了。同理,我们也可推送镜像到私有仓库,只需要将imageName指定成类似于如下的形式即可:
<imageName>localhost:5000/itmuch/microservice-discovery-eureka:0.0.4</imageName>
TIPS
(1) 以上示例中,我们是通过imageName指定镜像名称和标签的,例如:
<imageName>itmuch/microservice-discovery-eureka:0.0.4</imageName>
我们也可借助imageTags元素更为灵活地指定镜像名称和标签,例如:
<configuration>
<imageName>itmuch/microservice-discovery-eureka</imageName>
<imageTags>
<imageTag>0.0.5</imageTag>
<imageTag>latest</imageTag>
</imageTags>
...
<configuration>
这样就可为同一个镜像指定两个标签。
(2) 我们也可在执行构建命令时,使用dockerImageTags参数指定标签名称,例如:
mvn clean package docker:build -DpushImageTags -DdockerImageTags=latest -DdockerImageTags=another-tag
(3) 如需重复构建相同标签名称的镜像,可将forceTags设为true,这样就会覆盖构建相同标签的镜像。
<configuration>
<!-- optionally overwrite tags every time image is built with docker:build -->
<forceTags>true</forceTags>
<configuration>
拓展阅读
(1) Spotify是全球最大的正版流媒体音乐服务平台。
- 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐
- 1602: [Usaco2008 Oct]牧场行走
- 【LeetCode 500】关关的刷题日记27 Keyboard Row
- 1601: [Usaco2008 Oct]灌水
- 1657: [Usaco2006 Mar]Mooo 奶牛的歌声
- 1610: [Usaco2008 Feb]Line连线游戏
- 1012: [JSOI2008]最大数maxnumber
- 1430: 小猴打架
- 1202: [HNOI2005]狡猾的商人
- 1059: [ZJOI2007]矩阵游戏
- 3039: 玉蟾宫
- 大公司都有哪些开源项目之腾讯
- Vue拖拽组件开发实例
- 一小时培训之神经网络入门
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一分钟学Python| Python的函数(上)
- 数据分析与数据挖掘 - 07数据处理
- MySql8.0.19最新版本创建用户分配权限演示,You have an error in your SQL syntax权限分配问题解决方法
- linux服务器oracle数据库导出dmp文件功能演示,备份数据库命令。exp命令显示command not found解决方法,EXP-00028: 无法打开dmp进行写入问题解决
- oracle数据库exp命令导入导出dmp文件演示,oracle数据库备份还原功能
- oracle数据库impdp导入dmp文件功能演示,imp导入IMP-00038: Could not convert to environment character sets handle问题解决
- 弄懂这 5 个问题,拿下 Python 迭代器!
- windows、linux下命令行登录oracle数据库方法,查询sga参数值sql语句
- oracle数据库查询open_cursors值的sql语句,达梦数据库查询MAX_SESSION_STATEMENT值方法,MAX_SESSION_STATEMENT的最大值、上限是多少。
- 达梦数据库启用日志方法,达梦数据库查看日志是否启用,达梦数据库日志文件位置查找
- JavaScript 技术篇 - js 查看哪个元素获取了焦点,js 指定元素获取焦点方法
- 工作10年后,再看String s = new String("xyz") 创建了几个对象?
- Linux达梦数据库:通过disql登录命令行操作数据库,打开达梦数据库自带的数据库管理连接工具
- Dbvis数据库连接工具将查询出数据转化为sql插入语句方法
- JavaScript 技术篇 - js通过xpath路径定位元素方法