maven实战技巧「docker实战系列」使用maven插件构建docker镜像的方法(代码片段)

洛神灬殇 洛神灬殇     2023-01-02     817

关键词:

使用Maven插件构建Docker镜像的方法

本文介绍了使用Maven插件构建Docker镜像的方法,分享给大家,具体如下:

工具

工欲善其事,必先利其器。笔者经过调研,有以下几款Docker的Maven插件进入笔者视野。

插件名称+官方地址

  • 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

修改宿主机配置(docker可以远程访问)

  • 修改宿主机的docker配置,让其支持远程访问。
vi /usr/lib/systemd/system/docker.service

开启docker远程API,修改docker配置文件 docker.service进入编辑模式后。

ExecStart=后添加配置-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

保存后退出,重新加载配置文件#systemctl daemon-reload ,启动docker #systemctl start docker 。

  • 刷新配置,重新服务
systemctl daemon-reload
systemctl restart docker

配置 DOCKER_HOST

docker-maven-plugin 插件默认连接本地 Docker 地址为:localhost:2375,所以我们需要先设置下环境变量。

DOCKER_HOST=tcp://<host>:2375

注意:如果没有设置 DOCKER_HOST 环境变量,可以命令行显示指定 DOCKER_HOST 来执行,如我本机指定 DOCKER_HOST:DOCKER_HOST=tcp://:2375

例如

  • ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock ,这里就写4个0,你可别改成自己的ip哦,

  • 输入#netstat -anp|grep 2375 显示docker正在监听2375端口,输入#curl 127.0.0.1:2375/info 显示一大堆信息,证明远程api就弄好了

  • 在windows系统环境变量中新建DOCKER_HOST,值为tcp://10.100.74.220:2375,(你改成你自己的docker服务器ip地址)

使用插件构建Docker镜像

在我们持续集成过程中,项目工程一般使用 Maven 编译打包,然后生成镜像,通过镜像上线,能够大大提供上线效率,同时能够快速动态扩容,快速回滚,着实很方便。docker-maven-plugin 插件就是为了帮助我们在Maven工程中,通过简单的配置,自动生成镜像并推送到仓库中

添加插件

在pom.xml中添加下面这段:

 <build>
	 添加相关的镜像插件
 </build>

构建镜像

构建镜像可以使用一下两种方式,第一种是将构建信息指定到 POM 中,第二种是使用已存在的 Dockerfile 构建。(支持将 FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD 信息配置在 POM 中,不需要使用 Dockerfile 配置。)

  • 第一种方式,支持将 FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD 信息配置在 POM 中,不需要使用 Dockerfile 配置

  • 第二种方式,如果使用 VOLUME 或其他 Dockerfile 中的命令的时候,需要创建一个 Dockerfile,并在 POM 中配置 dockerDirectory 来指定路径即可。(创建一个 Dockerfile,并在 POM 中配置 dockerDirectory 来指定路径即可)

添加docker-maven-plugin
<plugin>
  <groupId>com.spotify</groupId>
  <artifactId>docker-maven-plugin</artifactId>
  <version>0.4.13</version>
  <configuration>
	 <dockerDirectory>$project.basedir/src/main/docker</dockerDirectory>  
    <imageName>dockerhub名称/imageName</imageName> 
	 <imageTags>
         <imageTag>imageTag</imageTag>
     </imageTags>
    <baseImage>baseImage</baseImage>
    <entryPoint>end[point]</entryPoint>
	<maintainer>author author@email.com</maintainer>
     <workdir>/ROOT</workdir>
    <resources>
      <resource>
        <targetPath>/</targetPath> 
        <directory>$project.build.directory</directory>
        <include>$project.build.finalName.jar</include> 
      </resource>
    </resources>
  </configuration>
</plugin>
  • dockerhub名称/imageName:

    • dockerhub名称:对应DockerHub用户名,,一定要是符合正则[a-z0-9-_.]的,否则构建不会成功

    • imageName:对应 DockerHub 仓库名,一定要是符合正则[a-z0-9-_.]的,否则构建不会成功

    • 可以直接指定: p r o j e c t . g r o u p I d / project.groupId/ project.groupId/project.artifactId

  • imageTag:镜像标签,相当于标签或者版本,latest。

  • baseImage: 指定基础镜像,等同 FROM 指令,例如:java,当然可以不用,直接在dockerfile文件中生成。

  • endpoint:// 等同于 ENTRYPOINT 指令,例如: [“java”,“-jar”,“app.jar”]

这里是复制 jar 包到 docker 容器指定目录配置,也可以写到 Dockerfile中

  • project.build.directory:指定要复制的根目录,$project.build.directory 表示 target 目录。

  • project.build.finalName:指定要复制的文件,$project.build.finalName.jar 指打包后的 jar 文件。

  • resources.resource.targetPath:将打包后的资源文件复制到该目录;

  • resources.resource.directory:需要复制的文件所在目录,maven打包的应用jar包保存在target目录下面;

  • resources.resource.include:需要复制的文件,打包好的应用jar包。

读取 Dockerfile 文件就不必指定 baseImage 和 entrypoint

  • 指定要读取的Dockerfile文件:
<dockerDirectory>$project.basedir/src/main/docker</dockerDirectory>

创建Dockerfile

\\src\\main\\docker

内容如下
FROM java:8
VOLUME /tmp
ADD admin-service-80-0.0.1-SNAPSHOT.jar admin-service-80.jar
RUN bash -c 'touch /admin-service-80.jar'
EXPOSE 80
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","$project.build.finalName.jar"]
执行以下命令构建 Docker 镜像

mvn clean package 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 docker_maven@email.com
 ---> 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 查看刚才构建的镜像

执行命令

  • 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 文件中指定配置如下:

<build>
  <plugins>
    ...
    <plugin>
      <configuration>
        ...
        <imageTags>
           <imageTag>imageTag_1</imageTag>
           <imageTag>imageTag_2</imageTag>
        </imageTags>
      </configuration>
    </plugin>
    ...
  </plugins>
</build>

绑定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 操作了。

以上示例,当我们执行mvn package时,执行 build、tag 操作,当执行mvn deploy时,执行build、tag、push 操作。如果我们想跳过 docker 某个过程时,只需要:

  • -DskipDockerBuild 跳过 build 镜像
  • -DskipDockerTag 跳过 tag 镜像
  • -DskipDockerPush 跳过 push 镜像
  • -DskipDocker 跳过整个阶段

例如:我们想执行 package 时,跳过 tag 过程,那么就需要mvn package -DskipDockerTag。

<build>
    <plugins>
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.0.0</version>
            <configuration>
                <imageName>mavendemo</imageName>
                <baseImage>java</baseImage>
                <maintainer>docker_maven docker_maven@email.com</maintainer>
                <workdir>/ROOT</workdir>
                <cmd>["java", "-version"]</cmd>
                <entryPoint>["java", "-jar", "$project.build.finalName.jar"]</entryPoint>
                <resources>
                    <resource>
                        <targetPath>/ROOT</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>mavendemo:latest</image>
                        <newName>docker.io/wanyang3/mavendemo:$project.version</newName>
                    </configuration>
                </execution>
                <execution>
                    <id>push-image</id>
                    <phase>deploy</phase>
                    <goals>
                        <goal>push</goal>
                    </goals>
                    <configuration>
                        <imageName>docker.io/wanyang3/mavendemo:$project.version</imageName>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

docker-maven-plugin 插件还提供了很多很实用的配置,稍微列举几个参数吧。

安全认证配置

当我们 push 镜像到 Docker 仓库中时,不管是共有还是私有,经常会需要安全认证,登录完成之后才可以进行操作。当然,我们可以通过命令行 docker login -u user_name -p password docker_registry_host 登录,但是对于自动化流程来说,就不是很方便了。使用 docker-maven-plugin 插件我们可以很容易实现安全认证

首先在 Maven 的配置文件 setting.xml 中增加相关 server 配置,主要配置 Docker registry用户认证信息

<servers>
  <server>
    <id>my-docker-registry</id>
    <username>wanyang3</username>
    <password>12345678</password>
    <configuration>
      <email>wanyang3@mail.com</email>
    </configuration>
  </server>
</servers>

然后只需要在 pom.xml 中使用 server id 即可。

<plugin>
  <plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>1.0.0</version>
    <configuration>
      <imageName>registry.example.com/wanyang3/mavendemo:v1.0.0</imageName>
      ...
      <serverId>my-docker-registry</serverId>
    </configuration>
  </plugin>

使用私有Docker仓库地址

实际工作环境中,我们需要 push 镜像到我们私有 Docker 仓库中,使用d ocker-maven-plugin 插件我们也是很容易实现,有几种方式实现

修改 POM 文件 imageName 操作

<configuration>
    <imageName>privateImageHubUrl/imageName/tag</imageName>
    ...
</configuration>

以以上的格式进行输出即可。

修改 POM 文件中 newName 操作

<configuration>
    <imageName>mavendemo</imageName>
    ...
</configuration>
<execution>
    <id>tag-image</id>
    <phase>package</phase>
    <goals>
        <goal>tag</goal>
    </goals>
    <configuration>
        <image>mavendemo</image>
        <newName>privateImageHubUrl/imageName/tag</newName>
    </configuration>
</execution>

重新启动Docker服务

systemctl stop docker
systemctl start docker

开启防火墙的Docker构建端口

firewall-cmd --zone=public --add-port=2375/tcp --permanentfirewall-cmd --reload

sql开发实战技巧系列:sql排序的那些事(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

sql开发实战技巧系列:从执行计划讨论unionall与空字符串&union与or的使用注意事项(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

sql开发实战技巧系列:关于sql不得不说的那些事(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

sql开发实战技巧系列(三十四):数仓报表场景☞如何对数据分级并行转为列(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

maven实战技巧「插件使用专题」maven-archetype插件创建自定义maven项目骨架(代码片段)

技术推荐自定义ArchetypeMaven骨架/以当前项目为模板创建maven骨架,可以参考http://maven.apache.org/archetype/maven-archetype-plugin/advanced-usage.html,详细介绍了如何快速创建和使用Archetype。技术背景在工作过程中必然会遇到创建项目... 查看详情

sql开发实战技巧系列:从执行计划看notinnotexists和leftjoin效率,记住内外关联条件不要乱放(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

sql开发实战技巧系列(十六):数据仓库中时间类型操作(初级)日月年时分秒之差及时间间隔计算(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

maven实战技巧「插件使用专题」maven-assembly插件实现自定义打包(代码片段)

前提概要最近我们项目越来越多了,然后我就在想如何才能把基础服务的打包方式统一起来,并且可以实现按照我们的要求来生成,通过研究,我们通过使用maven的assembly插件完美的实现了该需求,爽爆了有木... 查看详情

sql开发实战技巧系列:从执行计划看inexists和innerjoin效率,我们要分场景不要死记网上结论(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

sql开发实战技巧系列(十三):讨论一下常用聚集函数&通过执行计划看sum()over()对员工工资进行累加(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

sql开发实战技巧系列(十八):数据仓库中时间类型操作(进阶)intervalextract以及如何确定一年是否为闰年及周的计算(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

sql开发实战技巧系列(二十二):数仓报表场景☞从分析函数效率一定快吗聊一聊结果集分页和隔行抽样实现方式(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

实战:基于springcloud+docker构建微服务

本系列记录学习 spring-cloud-microservice-example的实战过程,并对利用springcloud+docker构建端到端的微服务架构技术进行解析。0.安装前的准备,下列软件需要安装。Maven3Java8DockerDockerCompose我的环境Ubuntu16.04Javaopenjdk1.8.0Docker18.03.1-cedoc... 查看详情

[maven实战]仓库(本地仓库,远程仓库,镜像)

1.简介maven可以在某个位置统一存储所有maven项目共享的构件,这个统一的位置就是仓库。实际的Maven项目将不会各自存储其依赖文件,它们只需要声明这些依赖的坐标,在需要的时候(例如,编译项目的时候需要将依赖加入到classp... 查看详情

sql开发实战技巧系列(十五):查找最值所在行数据信息及快速计算总和百之max/min()keep()over()fisrt_valuelast_valueratio_to_report(代码片段)

系列文章目录【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事【SQL开发实战技巧】系列(二):简单单表查询【SQL开发实战技巧】系列(三):SQL排序的那些事【SQL开发实战技巧】系列... 查看详情

spark入门实战系列--2.spark编译与部署(中)--hadoop编译安装

...及使用到安装包/测试数据可以在《倾情大奉送--Spark入门实战系列》获取1、编译Hadooop1.1 搭建环境1.1.1 安装并设置maven1. 下载maven安装包,建议安装3.0以上版本,本次安装选择的是maven3.0.5的二进制包,下载地址如下http:... 查看详情

docker系列文-----docker三大核心概念以及实战(nginx与mysql)(代码片段)

Docker系列文-----Docker三大核心概念以及实战(nginx与MySQL)(2)Docker三大核心概念一.镜像(Image)二.容器(Container)三.仓库(Repository)Docker的基本命令介绍1.查看自己的docker版本2. 查看详情

docker实战系列之docker端口映射错误解决方法(代码片段)

错误:Errorresponsefromdaemon:Cannotstartcontainerweb:iptablesfailed:iptables-tnat-ADOCKER-ptcp-d0/0--dport32797-jDNAT--to-destination172.17.0.30:5000!-idocker0:iptables:Nochain/target/matchbythatname.解决 查看详情