Docker与Spring Boot的集成:docker-maven-plugin使用

使用Spring Boot编写了一个微服务后,如何将构建应用并打包成Docker镜像,推送到Docker仓库,以供测试环境测试。

docker-maven-plugin插件可以完成这项任务,Github地址:https://github.com/spotify/docker-maven-plugin

该插件是基于Maven插件,用来构建Docker镜像,当然也可以通过在系统中配置Dockerfile的方式构建镜像。

目的

可以使用该插件在Maven项目中创建一个Docker镜像,比方说,build过程可以为Java服务输出一个可以运行该服务的Docker镜像。

步骤

Dockerfile提供了两种配置方式,一种是通过Dockerfile文件,一种是直接在pom.xml配置。

可以直接在pom.xml文件中指定base image, entry point, cmd, maintainerfiles,而不用通过Dockerfile的方式。

当然通过pom.xml文件的方式支持一些简单的命令,如果你需要volumn命令(或者其他pom.xml不支持使用的命令),还是需要通过将命令写入Dockerfile,并通过在pom.xml中配置dockerDirectory来引入该Dockerfile

默认情况下,该插件通过访问localhost:2375来连接本地Docker,可以通过设置DOCKER_HOST环境变量来连接Docker

DOCKER_HOST=tcp://<host>:2375

在pom中声明构建信息

下面的代码示例是创建了名为example的新镜像,将项目编译的jar包拷贝到镜像中,并设置了一个entrypoint去运行这个jar,在下面的代码中可以改变VERSION GOES HERE改变插件的版本,目前最新的版本是1.2.2

<build>
  <plugins>
    ...
    <plugin>
      <groupId>com.spotify</groupId>
      <artifactId>docker-maven-plugin</artifactId>
      <version>VERSION GOES HERE</version>
      <configuration>
        <imageName>example</imageName>
        <baseImage>java</baseImage>
        <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
        <!-- copy the service's jar file from target into the root directory of the image --> 
        <resources>
           <resource>
             <targetPath>/</targetPath>
             <directory>${project.build.directory}</directory>
             <include>${project.build.finalName}.jar</include>
           </resource>
        </resources>
      </configuration>
    </plugin>
    ...
  </plugins>
</build>

参数解释:

  • imageName: 镜像的名称,可以通过${project.groupId}/${project.artifactId}:${project.version}动态制定镜像名称。当然也可以在前面加上镜像地址,比如127.0.0.1:5000,以声明将构建好的镜像存储在本地
  • baseImage: 基础镜像,这里是相当于DockerfileFROM java
  • resources下的配置:构建时会生成Docker文件夹,这里指生成文件夹的内容来源,包含了mvn clean package之后的target的文件和生成的jar

使用Dockerfile

为了使用Dockerfile,必须在pom.xml的文件中通过dockerDirectory来指明Dockerfile文件的所在目录。如果配置了dockerDirectory, baseImage, maintainer, cmdentryPoint配置将忽略。下面的配置会将dockerDirectory的内容拷贝至${project.build.directory}/docker,使用resouces元素可以拷贝其他的文件,比如生成jar包文件。

<build>
  <plugins>
    ...
    <plugin>
      <groupId>com.spotify</groupId>
      <artifactId>docker-maven-plugin</artifactId>
      <version>VERSION GOES HERE</version>
      <configuration>
        <imageName>example</imageName>
        <dockerDirectory>docker</dockerDirectory>
        <resources>
           <resource>
             <targetPath>/</targetPath>
             <directory>${project.build.directory}</directory>
             <include>${project.build.finalName}.jar</include>
           </resource>
        </resources>
      </configuration>
    </plugin>
    ...
  </plugins>
</build>

使用

按照上面的配置之后,可以使用如下命令生成一个镜像

mvn clean package docker:build

将生成的镜像推送到镜像注册中心,通过pushImage标签

mvn clean package docker:build -DpushImage

如果推送制定tags 的镜像,可使用pushImageTag标签

mvn clean package docker:build -DpushImageTag

为了使得上述的命令执行成功,需要在pom中配置imageTag,可以配置多个imageTag

<build>
  <plugins>
    ...
    <plugin>
      <configuration>
        ...
        <imageTags>
           <imageTag>${project.version}</imageTag>
           <imageTag>latest</imageTag>
        </imageTags>
      </configuration>
    </plugin>
    ...
  </plugins>
</build>

如果想强制Docker在每次新的构建上覆盖镜像tags,可配置foreceTags

<build>
  <plugins>
    ...
    <plugin>
      <configuration>
        ...
        <!-- optionally overwrite tags every time image is built with docker:build -->
        <forceTags>true</forceTags>
        <imageTags>
           ...
        </imageTags>
      </configuration>
    </plugin>
    ...
  </plugins>
</build>

也可以在构建的命令行上添加上镜像tags:

mvn ... docker:build -DpushImageTags -DdockerImageTags=latest -DdockerImageTags=another-tag

绑定docker命令到maven phases

可以将build,tag&push目标绑定到maven phases,这样仅仅通过运行mvn deploy命令就能完成项目build,tag,push。如果有一个多模块项目,当通过绑定,在父项目运行maven命令的同时,子模块项目可以自动构建镜像

<plugin>
  <groupId>com.spotify</groupId>
  <artifactId>docker-maven-plugin</artifactId>
  <version>VERSION GOES HERE</version>
  <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>my-image:${project.version}</image>
        <newName>registry.example.com/my-image:${project.version}</newName>
      </configuration>
    </execution>
    <execution>
      <id>push-image</id>
      <phase>deploy</phase>
      <goals>
        <goal>push</goal>
      </goals>
      <configuration>
        <imageName>registry.example.com/my-image:${project.version}</imageName>
      </configuration>
    </execution>        
  </executions>
</plugin>

可以通过以下命令跳过Docker构建的阶段

  • -DskipDockerBuild 跳过镜像构建
  • -DskipDockerTag 跳过镜像tag设置
  • -DskipDockerPush 跳过镜像推送
  • -DskipDocker 跳过所有的镜像构建目标

删除一个名称为foobar的镜像,可以运行如下命令

mvn docker:removeImage -DimageName=foobar

获取完成的配置选项列表,可运行如下命令:

mvn com.spotify:docker-maven-plugin:<version>:help -Ddetail=true

使用私有镜像中心

为了将镜像推送到私有的镜像注册中心,Docker需要在镜像tag之前用注册中心的地址作为前缀。比如需要推送my-imageregistry.example.com,那么这个镜像需要命名为registry.example.com/my-image

最简单的方法就是在<imageName>中配置:

<plugin>
  <groupId>com.spotify</groupId>
  <artifactId>docker-maven-plugin</artifactId>
  <configuration>
    <imageName>registry.example.com/my-image</imageName>
    ...

这样,当通过命令docker:build -DpushImage或者docker:push推送镜像时,Docker引擎会将镜像推送到registry.example.com

当然也可以在docker:build命令中通过docker:tag -DpushImage对创建的镜像加上私有镜像注册中心的地址,如不配置,则会推送到默认的镜像中心,即Docker Hub,也可如下这样配置:

<plugin>
  <groupId>com.spotify</groupId>
  <artifactId>docker-maven-plugin</artifactId>
  <configuration>
    <imageName>my-image</imageName>
    ...
  </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>my-image</image>
        <newName>registry.example.com/my-image</newName>
      </configuration>
    </execution>
  </executions>
</plugin>

认证

支持三种认证方式:

读取本地配置文件,自动认证

从1.0.0版本之后,docker-maven-plugin插件会自动读取到docker-cli的认证配置,默认在~/.dockercfg~/.docker/config.json,而无需额外的配置

GCR认证

如果本机配置DOCKER_GOOGLE_CREDENTIALS的环境变量,则会使用GCR认证。

Server认证

也可以在Maven的settings.xml配置认证信息:

<servers>
  <server>
    <id>docker-hub</id>
    <username>foo</username>
    <password>secret-password</password>
    <configuration>
      <email>foo@foo.bar</email>
    </configuration>
  </server>
</servers>

pom.xml则通过如下配置关联上述server id

<plugin>
  <plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>VERSION GOES HERE</version>
    <configuration>
      [...]
      <serverId>docker-hub</serverId>
      <registryUrl>https://index.docker.io/v1/</registryUrl>
    </configuration>
  </plugin>
</plugins>

以上三种配置方式中,通过读取客户端默认配置的优先级更高。

在server配置中加密密码

为了不在配置文件中不暴露明文密码,可以使用maven加密功能对密码进行加密,通过{ }方式都认为是被加密的密码

<servers>
  <server>
    <id>docker-hub</id>
    <username>foo</username>
    <password>{gc4QPLrlgPwHZjAhPw8JPuGzaPitzuyjeBojwCz88j4=}</password>
  </server>
</servers>

注意:构建的镜像名称不要含有SNAPSHOT,因为镜像名称只允许[a-z0-9-_.]

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/04/01/docker-and-spring-boot-integration-docker-aven-plugin-usage/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Docker与Spring Boot的集成:docker-maven-plugin使用
使用Spring Boot编写了一个微服务后,如何将构建应用并打包成Docker镜像,推送到Docker仓库,以供测试环境测试。 docker-maven-plugin插件可以完成这项任务,G……
<<上一篇
下一篇>>
文章目录
关闭
目 录