为什么要用插件

主要还是自动化的考虑,如果额外使用Dockerfile进行镜像生成,可能会需要自己手动指定jar/war位置,并且打包和生成镜像间不同步,带来很多琐碎的工作。

插件选择

使用比较多的是spotify的插件:https://github.com/spotify/docker-maven-plugin

https://github.com/spotify/dockerfile-maven。

但这里我选择另一款插件:https://github.com/fabric8io/docker-maven-plugin。

因为他文档比较详细,在使用上也比较方便。

文档地址:https://dmp.fabric8.io/

示例

这里使用一个spring boot项目,只有一个最简单的HelloController,如下:

@RestController
public class HelloController {
@GetMapping("/")
public String hello() {
return "hello";
}
}

pom.xml改动如下:

<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.23.0</version>
<configuration>
<dockerHost>tcp://192.168.99.100:2376</dockerHost>
<certPath>C:\Users\fairjm\.docker\machine\machines\default</certPath>
<images>
<image>
<name>${project.name}:${project.version}</name>
<build>
<from>openjdk:8-jre</from>
<args>
<JAR_FILE>${project.name}-${project.version}.jar</JAR_FILE>
</args>
<assembly>
<descriptorRef>artifact</descriptorRef>
</assembly>
<entryPoint>["java"]</entryPoint>
<cmd>["-jar","maven/${project.name}-${project.version}.jar"]</cmd>
</build>
<run>
<ports>
<port>8888:8080</port>
</ports>
</run>
</image>
</images>
</configuration>
</plugin>

这里使用了在xml里写操作而不是使用Dockerfile的方式,个人感觉这种方式更加简单一点,不需要额外再维护一份文件,和Dockerfile相比使用的语法(注意entrypoint和cmd)也类似。

接下来介绍一下configuration配置。

dockerHostcertPath是连接docker使用,毕竟插件本身不包含docker和对应功能只是调用docker提供的API。

这两个值在docker toolbox上可以通过docker-machine env获得。

$ docker-machine env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="C:\Users\fairjm\.docker\machine\machines\default"
export DOCKER_MACHINE_NAME="default"
export COMPOSE_CONVERT_WINDOWS_PATHS="true"
# Run this command to configure your shell:
# eval $("D:\Docker Toolbox\docker-machine.exe" env)

image的build指定了构建相关的设置:

  • name指定image名,这里使用了项目名,tag使用项目版本;
  • from指定基于的image,和Dockerfile的FROM一致;
  • args和ARG一致(在这个例子中没有实际意义);
  • assembly用来定义哪些文件进入镜像中,使用了插件已经定义好的行为,spring-boot生成的是fat jar不需要拷贝依赖所以选择了artifact。这个的配置比较丰富,可以查看文档获取更多的信息。
  • entryPoint和cmd也对应同样的Dockerfile命令。

接着通过mvn clean package docker:build执行打包和build

[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ docker-test ---
[INFO] Building jar: D:\sts_workspace\docker-test\target\docker-test-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:1.5.9.RELEASE:repackage (default) @ docker-test ---
[INFO]
[INFO] --- docker-maven-plugin:0.23.0:build (default-cli) @ docker-test ---
[INFO] Copying files to D:\sts_workspace\docker-test\target\docker\docker-test\0.0.1-SNAPSHOT\build\maven
[INFO] Building tar: D:\sts_workspace\docker-test\target\docker\docker-test\0.0.1-SNAPSHOT\tmp\docker-build.tar
[INFO] DOCKER> [docker-test:0.0.1-SNAPSHOT]: Created docker-build.tar in 1 second
[INFO] DOCKER> [docker-test:0.0.1-SNAPSHOT]: Built image sha256:303c3
[INFO] DOCKER> [docker-test:0.0.1-SNAPSHOT]: Removed old image sha256:ea8a7
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

完成打包,在对应连接的docker上也会出现这个镜像:

$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker-test 0.0.1-SNAPSHOT 303c39c7d253 13 seconds ago 552MB

run指定了运行参数 这里将host的8888和容器的8080绑定,可以使用mvn docker:start启动,访问8888端口即可连接到服务器。

与其配对的是mvn docker:stop,可以停止并移除启动的容器。

示例2

上述使用xml的配置方式,这里再简单描述一下使用Dockerfile的配置方式。

在进行一些操作的时候,可以发现使用xml会有些问题,比如指令的执行顺序。

该插件xml的执行顺序和命令的定义顺序不一定一致,可能会带来一些问题,比如将<user>放于<runCmds>前但还是<runCmds>先触发,一些需要root权限的命令就会失败。

比如这个issus(但不确定是feature还是bug,感觉是feature):https://github.com/fabric8io/docker-maven-plugin/issues/913

这时候就需要直接使用Dockerfile来进行配置。

这里取一个实际的打成war的工程。

插件配置如下:

<images>
<image>
<name>${project.name}:${project.version}</name>
<build>
<assembly>
<descriptorRef>rootWar</descriptorRef>
</assembly>
<dockerFile>Dockerfile</dockerFile>
</build>
<run>
<ports>
<port>8888:8080</port>
</ports>
</run>
</image>
</images>

这里更改了descriptorRef,换成rootWar,这会将target下的项目war拷贝到maven\下并且取名为ROOT.war

Dockerfile默认放置的位置是src/main/docker,我们在这里建对应的文件:

FROM jetty
USER root
ENV JAVA_OPTIONS=-Xmx1g
RUN mkdir -p /root/xxx && touch /root/xxx/yyy && echo zz > /root/xxx/yyy
COPY maven/ /var/lib/jetty/webapps

基本和上面的配置类似,base image改为了jetty,查看jetty的Dockerfile可以发现他使用了一个新用户jetty,使用这个用户无法在root下建立目录,并且由于项目本身之前使用sudo执行的,所以为了能正常运行选择使用root用户。

最后一步将ROOT.war拷贝到jetty的webapps目录下。

关于maven/这个目录,在打包后,会在target下生成target\docker\项目名\0.0.1-SNAPSHOT\build,对应的Dockerfilemaven\就在这个目录下,实际执行的不是src/main/docker/Dockerfile,而是拷贝到上述目录下的Dockerfile,此外使用xml的方式也是在这个位置生成了一份Dockerfile(USER 总是被放置于最后...)。

更多

本文简要说明了使用fabric8的docker maven插件进行构建运行相关的操作,该插件还有其他的功能可以通过上面的文档获取帮助。

源码下载(示例1)

https://github.com/fairjm/spring-boot-docker

使用maven插件构建docker镜像的更多相关文章

  1. Maven插件构建Docker镜像

    背景 微服务架构下,微服务在带来良好的设计和架构理念的同时,也带来了运维上的额外复杂性,尤其是在服务部署和服务监控上.单体应用是集中式的,就一个单体跑在一起,部署和管理的时候非常简单,而微服务是一个网 ...

  2. docker(七) 使用dockerfile-maven-plugin插件构建docker镜像

    在dockerfile-maven-plugin插件出现之前,还有一个maven插件是docker-maven-plugin,是由同一个作者创造,作者明确表示推荐使用dockerfile-maven- ...

  3. docker(六) 使用docker-maven-plugin插件构建docker镜像(已过时)

    可以参考博客:https://blog.csdn.net/aixiaoyang168/article/details/77453974 docker-maven-plugin官网推荐在新项目中使用do ...

  4. 使用docker-maven-plugin插件构建docker镜像(已过时)

    可以参考博客:https://blog.csdn.net/aixiaoyang168/article/details/77453974 docker-maven-plugin官网推荐在新项目中使用do ...

  5. 使用docker Maven插件本地构建docker镜像并发布到远程服务器

    1.登录网站https://start.spring.io/,生成一个基本的SpringBoot应用. 2.将应用导入Eclipse IDE并创建Application类.目录结构如下: Applic ...

  6. 使用Maven插件构建Spring Boot应用程序镜像

    使用Maven插件构建Spring Boot应用程序的Docker镜像. 环境准备 1.Linux系统 2.安装JDK,Maven 3.安装Docker 应用实践 1.在应用程序根目录下添加Docke ...

  7. 在sun jdk 8镜像基础上构建maven 3的docker镜像

    2019独角兽企业重金招聘Python工程师标准>>> 在https://my.oschina.net/ytqvip/blog/1595054文章的sun jdk 8镜像基础上构建m ...

  8. 使用Jenkins pipeline流水线构建docker镜像和发布

    新建一个pipeline job 选择Pipeline任务,然后进入配置页面. 对于Pipeline, Definition选择 "Pipeline script from SCM" ...

  9. 使用Buildpacks高效构建Docker镜像

    1. 前言 Spring Boot 2.3.0.RELEASE 正式发布了几天了,其中有个新的特性:可以将Spring Boot应用代码直接打包为Docker镜像.这是什么科技?我赶紧去官网查了一番才 ...

随机推荐

  1. mysql编译好的简单安装

    .创建mysql用户的账号 useradd mysql .下载mysql编译好的压缩包 .安装mysql yum -y install numactl libaio 安装依赖库 tar -zxvf m ...

  2. Quartz错过任务执行时间的处理机制(Misfire处理规则 )

    调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则 CronTrigger withMisfireHandlingInstr ...

  3. 单点登录的三种实现方式 转自: https://blog.csdn.net/python_tty/article/details/53113612

    单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得 ...

  4. union: apt command

    # when you use 'dpkg -i $software' failed, you can install the dependency of this software by # this ...

  5. (Swiftmailer)高效的PHP邮件发送库

    Swiftmailer是一个类似PHPMailer邮件发送组件,它也支持HTML格式.附件发送,但它发送效率相当高,成功率也非常高,很多PHP框架都集成了Swiftmailer. Swiftmaile ...

  6. 初入TensorFlow————配置TensorFlow

    能看到这说明你对python已经有一定的了解了,因此很多基础直接跳过. 一.TensorFlow环境配置: TensorFlow的环境配置在网上很多的教程都是用anaconda的方式,但是很容易出现冲 ...

  7. DataStructs.h

    #ifndef _DATASTRUCS_H__ #define _DATASTRUCS_H__ #include <systemc.h> #include "GlobalPara ...

  8. 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP

    不管是app的下载链接还是普通文件的链接在微信内置浏览器或者QQ内置浏览器都会被屏蔽.这是微信对第三方下载域名实施的拦截政策.被拦截了用户在微信内打开就会提示“已停止访问该网页”. 那么当我们遇到这个 ...

  9. nice coding (与其亡羊补牢,不如未雨绸缪)

    一.需求前 架构规范 建模规范 编码规范(流程控制,方法抽取,日志打印等) <Effective Java> <Design Patterns> 二.需求中 1. 明确需求(别 ...

  10. 网页偶现性崩溃-chrome

    简介: 项目前台框架:Angular2 + Bootstrap(日期等组件) + Echarts + 响应式(包括页面.字体缩放:rem) chrome版本:多个版本测试均有此问题. 表现: 订单详情 ...