1、docker-maven-plugin 介绍
在我们持续集成过程中,项目工程一般使用 Maven 编译打包,然后生成镜像,通过镜像上线,能够大大提供上线效率,同时能够快速动态扩容,快速回滚,着实很方便。docker-maven-plugin 插件就是为了帮助我们在Maven工程中,通过简单的配置,自动生成镜像并推送到仓库中。
2、环境、软件准备
本次演示环境,我是在本机 Mac OX 上操作,以下是安装的软件及版本:
- Docker:version 17.03.1-ce
- Maven:version 3.3.9
- Java: version 1.8.0_91
- docker-maven-plugin:1.0.0
注意:这里我们要测试 Java Maven 项目用 docker-maven 插件打镜像,上传镜像等操作,所以需要先安装一下 Docker、Maven、Java,这里忽略安装过程。
3、Demo 示例
3.1 配置 DOCKER_HOST
docker-maven-plugin 插件默认连接本地 Docker 地址为:localhost:2375,所以我们需要先设置下环境变量。
DOCKER_HOST=tcp://:2375
注意:如果没有设置 DOCKER_HOST
环境变量,可以命令行显示指定 DOCKER_HOST
来执行,如我本机指定 DOCKER_HOST:DOCKER_HOST=unix:///var/run/docker.sock mvn clean install docker:build
。
3.2 示例构建镜像
构建镜像可以使用一下两种方式,第一种是将构建信息指定到 POM 中,第二种是使用已存在的 Dockerfile 构建。
第一种方式,支持将 FROM
, ENTRYPOINT
, CMD
, MAINTAINER
以及 ADD
信息配置在 POM 中,不需要使用 Dockerfile 配置。但是如果使用 VOLUME
或其他 Dockerfile 中的命令的时候,需要使用第二种方式,创建一个 Dockerfile,并在 POM 中配置 dockerDirectory
来指定路径即可。
这里我们以一个 Java Maven 项目 mavendemo 作为示例演示一下。
3.2.1 指定构建信息到 POM 中构建
<build> <plugins> <plugin> <groupId>com.spotifygroupId> <artifactId>docker-maven-pluginartifactId> <version>1.0.0version> <configuration> <imageName>mavendemoimageName> <baseImage>javabaseImage> <maintainer>docker_maven [email protected]maintainer> <workdir>/ROOTworkdir> <cmd>["java", "-version"]cmd> <entryPoint>["java", "-jar", "${project.build.finalName}.jar"]entryPoint> <resources> <resource> <targetPath>/ROOTtargetPath> <directory>${project.build.directory}directory> <include>${project.build.finalName}.jarinclude> resource> resources> configuration> plugin> plugins> build>
3.2.2 使用 Dockerfile 构建
pom.xml配置
<build> <plugins> <plugin> <groupId>com.spotifygroupId> <artifactId>docker-maven-pluginartifactId> <version>1.0.0version> <configuration> <imageName>mavendemoimageName> <dockerDirectory>${basedir}/dockerdockerDirectory> <resources> <resource> <targetPath>/ROOTtargetPath> <directory>${project.build.directory}directory> <include>${project.build.finalName}.jarinclude> resource> resources> configuration> plugin> plugins> build> ${basedir}/docker/Dockerfile 配置 FROM java MAINTAINER docker_maven [email protected] WORKDIR /ROOT CMD ["java", "-version"] ENTRYPOINT ["java", "-jar", "${project.build.finalName}.jar"]
以上两种方式执行docker:build
效果是一样的,执行输出过程大致如下:
[INFO] --- docker-maven-plugin:1.0.0:build (default-cli) @ mavenDemo --- [INFO] Building image mavendemo Step 1/5 : FROM java ---> d23bdf5b1b1b Step 2/5 : MAINTAINER docker_maven [email protected] ---> Using cache ---> 2faf180d4a50 Step 3/5 : WORKDIR /ROOT ---> Using cache ---> 862210f7956a Step 4/5 : ENTRYPOINT java -jar mavenDemo.jar ---> Running in 96bbe83de6ec ---> c29009c88993 Removing intermediate container 96bbe83de6ec Step 5/5 : CMD java -version ---> Running in f69b8d2a75b1 ---> bc8d54014325 Removing intermediate container f69b8d2a75b1 Successfully built bc8d54014325
执行完成后,使用docker images
查看生成的镜像:
REPOSITORY TAG IMAGE ID CREATED SIZE
mavendemo latest 333b429536b2 38 minutes ago 643 MB
3.3 执行命令
mvn clean package docker:build
只执行 build 操作
mvn clean package docker:build -DpushImage
执行 build 完成后 push 镜像
mvn clean package docker:build -DpushImageTag
执行 build 并 push 指定 tag 的镜像
注意:这里必须指定至少一个 imageTag,它可以配置到 POM 中,也可以在命令行指定。命令行指定如下:mvn clean package docker:build -DpushImageTags -DdockerImageTags=imageTag_1 -DdockerImageTags=imageTag_2
,POM 文件中指定配置如下:
...
...
imageTag_1
imageTag_2
...
3.4 绑定Docker 命令到 Maven 各个阶段
我们可以绑定 Docker 命令到 Maven 各个阶段,我们可以把 Docker 分为 build、tag、push,然后分别绑定 Maven 的 package、deploy 阶段,此时,我们只需要执行mvn deploy
就可以完成整个 build、tag、push操作了,当我们执行mvn build
就只完成 build、tag 操作。除此此外,当我们想跳过某些步骤或者只执行某个步骤时,不需要修改 POM 文件,只需要指定跳过 docker 某个步骤即可。比如当我们工程已经配置好了自动化模板了,但是这次我们只需要打镜像到本地自测,不想执行 push 阶段,那么此时执行要指定参数-DskipDockerPush
就可跳过 push 操作了。
<build> <plugins> <plugin> <groupId>com.spotifygroupId> <artifactId>docker-maven-pluginartifactId> <version>1.0.0version> <configuration> <imageName>mavendemoimageName> <baseImage>javabaseImage> <maintainer>docker_maven [email protected]maintainer> <workdir>/ROOTworkdir> <cmd>["java", "-version"]cmd> <entryPoint>["java", "-jar", "${project.build.finalName}.jar"]entryPoint> <resources> <resource> <targetPath>/ROOTtargetPath> <directory>${project.build.directory}directory> <include>${project.build.finalName}.jarinclude> resource> resources> configuration> <executions> <execution> <id>build-imageid> <phase>packagephase> <goals> <