Spotify官方推荐Maven插件构建Docker镜像

Spotify官方推荐Maven插件构建Docker镜像

在之前的文章《用Maven插件打包Docker镜像》中,介绍了Spotify公司开发的docker-maven-plugin插件来自动构建Docker镜像。

然而在如下所示官方申明中,Spotify官方已经不再推荐使用该插件:

上面说明了不再推荐使用该插件的原因,转而推荐了另外一款由该公司开发的Maven插件dockerfile-maven-plugin。

今天我们就来介绍下如何使用该插件。

构建Docker镜像

1. 配置pom.xml

首先,在pom.xml中引入dockerfile-maven-plugin插件,并配置该插件。示例如下:

<plugin>
  <groupId>com.spotify</groupId>
  <artifactId>dockerfile-maven-plugin</artifactId>
  <version>1.4.13</version>
  <executions>
    <execution>
      <id>default</id>
      <goals>
        <goal>build</goal>
        <goal>push</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <repository>config-server</repository>
    <tag>${project.version}</tag>
    <buildArgs>
      <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
    </buildArgs>
  </configuration>
</plugin>

可以看到,该插件的配置比docker-maven-plugin更简单了。

repository指定docker镜像的repo名字。

tag指定docker镜像的tag。

buildArgs可以指定一个或多个变量,传递给Dockerfile,在Dockerfile中通过ARG指令进行引用。

另外,可以在execution中同时指定build和push目标。当运行mvn package时,会自动执行build目标,构建Docker镜像。当运行mvn deploy命令时,会自动执行push目标,将Docker镜像push到Docker仓库。

2. 编写Dockerfile

该插件不像docker-maven-plugin插件那样,可以不用准备Dockerfile,而是通过配置pom,由插件自动生成Dockerfile,并使用生成的Dockerfile构建Docker镜像。

该插件要求必须提供Dockerfile文件,而且要求放在项目根目录下,即与pom.xml同级目录。然后不需要像docker-maven-plugin插件那样需要指定Dockerfile文件存放路径的dockerDirectory参数。

而且,使用该插件,有一个重要的功能是,我们可以在Dockerfile中以target开头的相对路径来引用maven构建的artifact,如jar包。

如下面的Dockerfile文件内容所示:

FROM java:8
ARG JAR_FILE
ADD target/${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

我们看到,在ADD指令后面,使用了以target开头的相对路径来引用maven构建的jar包。

另外,从上面的示例中还看到,我们使用了该插件提供的另外一个新功能。正如前面提到的在pom.xml里通过buildArgs指定的变量,可以在Dockerfile中通过ARG指令引用进来,然后就可以在Dockerfile的其他地方用${variable_name}的方式引用由pom.xml传递进来的变量值。

3. 构建Docker镜像

使用该插件构建Docker镜像,需要有一个安装好的Docker运行环境。

且需要在运行该插件的机器上定义DOCKER_HOST环境变量,配置访问Docker的URL,如下:

export DOCKER_HOST=tcp://localhost:2375

上面的例子,是在Linux环境下定义的DOCKER_HOST环境变量,因为Docker安装在本机上,因此使用localhost。如果你的Docker运行环境不在本机,请使用Docker所在机器的IP

2375是为Docker开启的远程访问API的端口,如果你开启的是其他端口,请使用具体的端口。如果你的Docker没有开启远程访问API,请自行Google开启。

如果你要在Windwos上运行该Maven插件,同样需要在Windows上配置DOCKER_HOST环境变量,如下:

接下来,就可以运行maven命令来构建Docker镜像了:

mvn package

mvn dockerfile:build

命令执行成功后,运行docker命令检查镜像是否存在:

docker images


推送Docker镜像

Docker镜像构建好后,我们还可以使用该插件将镜像推送到Docker仓库,如Docker Hub。

下面介绍如何推送到Docker Hub。

1. 创建repository

首先,我们需要登录Docker Hub并创建一个repository,如下图所示,我们创建了config-server的repository:

2. 配置pom.xml

在pom.xml中为该插件配置正确的Docker镜像的repository名字,如下:

<configuration>
  <repository>longyonggang/config-server</repository>
  <tag>${project.version}</tag>
  <buildArgs>
    <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
  </buildArgs>
</configuration>

注意,repository的格式必须为:

<username>/<repository_name>

username就是登录Docker Hub的用户名,例如我的用户名是longyonggang。

repository_name就是上一步在Docker Hub上创建的repository名字。

3. 配置认证

接下来,需要为插件配置认证信息,即登录Docker Hub的用户名和密码。因为插件在push镜像前,需要登录Docker Hub。

有三种方式配置认证信息。

第一种:在pom.xml中配置认证信息

如下所示,可以直接在pom.xml为插件配置usnername和password:

<configuration>
  <repository>longyonggang/config-server</repository>
  <tag>${project.version}</tag>
  <username>longyonggang</username>
  <password>xxxx</password>
  <buildArgs>
    <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
  </buildArgs>
</configuration>


第二种:在settings.xml中配置server

如下所示,在maven的settings.xml中的servers下增加一个server配置:

<servers>
  <server>
    <id>docker.io</id>
    <username>longyonggang</username>
    <password>xxxx</password>
  </server>
</servers>

对于Docker Hub,server.id必须是docker.io

然后在pom.xml中指定useMavenSettingsForAuth为true:

<configuration>
  <repository>longyonggang/config-server</repository>
  <tag>${project.version}</tag>
  <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
  <buildArgs>
    <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
  </buildArgs>
</configuration>


第三种:直接在mvn命令行上提供认证信息

如果没有在pom.xml中配置认证信息,也没有在settings.xml中配置认证信息,那么我们还可以简单地在运行的mvn命令行上以参数的形式提供认证信息,如下所示:

mvn dockerfile:push -Ddockerfile.username=longyonggang -Ddockerfile.password=xxxx


第一种方式,由于需要在pom.xml中配置用户密码,而pom.xml一般都会随着源码一起提交到版本控制系统中,因此有暴露用户密码的风险。

第三种方式,在每次运行maven命令时,都需要额外提供用户名和密码,比较麻烦。

因此,一般推荐使用第二种方式。

4. push镜像

接下来,执行maven命令来push镜像。

对于前两种认证方式,我们可以直接运行mvn goal命令来push镜像:

mvn deploy

或者

mvn dockerfile:push


对于第三种认证方式,使用上面提到的命令来push镜像。

mvn dockerfile:push -Ddockerfile.username=longyonggang -Ddockerfile.password=xxxx


需要注意的是,如果你没有配置部署artifact的maven repository,请不要使用mvn deploy命令,因为它会执行maven-deploy-plugin的deploy目标,而由于没有配置要部署的远程maven repository,会报类似如下的错:

Deployment failed: repository element
was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter


在这种情况下,请使用下面的命令来push镜像:

mvn dockerfile:push


4. 检查镜像maven命令执行成功后,可以登录Docker Hub来检查镜像是否存在。

如下图所示:

END

发布于 2019-11-04