[CI/CD Technology Topic] "Docker Actual Combat Series" Method of Using Maven Plug-in to Build Docker Image

[CI/CD Technology Topic] "Docker Actual Combat Series" Method of Using Maven Plug-in to Build Docker Image

This article introduces the method of using the Maven plug-in to build a Docker image, and shares it with you, as follows:

tool

If a worker wants to do well, he must first sharpen his tools. After the author's research, the following Docker Maven plugins have entered the author's field of vision.

Plug-in name + official address

Modify the host configuration (docker can be accessed remotely)

  • Modify the docker configuration of the host to support remote access.
vi/usr/lib/systemd/system/docker.service copy the code

Open the docker remote API, modify the docker configuration file docker.service and enter the edit mode.

ExecStart=Add configuration after -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

Save and exit, reload the configuration file #systemctl daemon-reload, start docker #systemctl start docker.

  • Refresh the configuration and re-service
systemctl daemon-reload systemctl restart docker Copy code

Configure DOCKER_HOST

The docker-maven-plugin plugin connects to the local Docker address by default: localhost:2375, so we need to set the environment variables first.

DOCKER_HOST=tcp://<host>:2375Copy code

Note: If the DOCKER_HOST environment variable is not set, you can specify DOCKER_HOST to execute the command line display. For example, I specify DOCKER_HOST on my machine: DOCKER_HOST=tcp://:2375

E.g

  • ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock, write 4 zeros here, don t change it to your own ip ,

  • enter

    #netstat -anp|grep 2375
    Shows that docker is listening on port 2375, enter #curl 127.0.0.1:2375/info to display a lot of information, which proves that the remote api is done

  • Create a new DOCKER_HOST in the windows system environment variables, the value is tcp://10.100.74.220:2375, (you change to your own docker server ip address)

Use plugins to build Docker images

In our continuous integration process, project projects generally use Maven to compile and package, and then generate mirrors. Through mirroring to go online, it can greatly improve the online efficiency. At the same time, it can quickly and dynamically expand capacity and quickly roll back, which is really very convenient. The docker-maven-plugin plug-in is to help us in the Maven project, through simple configuration, automatically generate a mirror image and push it to the warehouse .

Add plugin

Add the following paragraph in pom.xml:

< build > Add related mirroring plugins </build > Copy code

Build image

There are two ways to build a mirror. The first is to specify the build information in the POM, and the second is to use an existing Dockerfile to build . (Support to configure FROM, ENTRYPOINT, CMD, MAINTAINER and ADD information in POM, without using Dockerfile configuration.)

  • The first method supports the configuration of FROM, ENTRYPOINT, CMD, MAINTAINER and ADD information in the POM, no need to use Dockerfile configuration

  • In the second way, if you use VOLUME or other commands in Dockerfile, you need to create a Dockerfile and configure dockerDirectory in the POM to specify the path. (Create a Dockerfile and configure dockerDirectory in the POM to specify the path)

Add docker-maven-plugin
< plugin > < groupId > com.spotify </groupId > < artifactId > docker-maven-plugin </artifactId > < version > 0.4.13 > $ {Project.build.directory} </version > < configuration > < dockerDirectory > ${project.basedir}/src/main/docker </dockerDirectory >    < imageName > {dockerhubName/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 </Directory > < the include > $} {project.build.finalName .jar </the include > </Resource > </Resources > </Configuration > </plugin > copy the code
  • {dockerhubname/imageName}:

    • dockerhub name: corresponding to the DockerHub username, it must conform to the regular [a-z0-9-_.], otherwise the build will not succeed

    • imageName: Corresponding to the DockerHub warehouse name, it must conform to the regular [a-z0-9-_.], otherwise the build will not succeed

    • You can directly specify:project.groupId/{project.groupId}/ {project.artifactId}

  • {imageTag}: Mirror tag, equivalent to tag or version, latest.

  • {baseImage}: Specify the base image, which is equivalent to the FROM command, for example: java, of course, it can be generated directly in the dockerfile file.

  • {endpoint}://Equivalent to ENTRYPOINT instruction, for example: ["java","-jar","app.jar"]

Here is to copy the jar package to the specified directory configuration of the docker container, or write it in the Dockerfile

  • {project.build.directory}: Specify the root directory to be copied, ${project.build.directory} represents the target directory.

  • {project.build.finalName}: Specify the file to be copied, ${project.build.finalName}.jar refers to the packaged jar file.

  • resources.resource.targetPath: Copy the packaged resource file to this directory;

  • resources.resource.directory: The directory where the files that need to be copied are located, and the application jar package packaged by maven is stored under the target directory;

  • resources.resource.include: files to be copied, packaged application jar package.

It is not necessary to specify baseImage and entrypoint to read the Dockerfile

  • Specify the Dockerfile file to be read:
<dockerDirectory> $ {project.basedir}/ src/main/docker </dockerDirectory> copy the code

Create Dockerfile

\src\main\docker

The content is as follows
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"] Copy code
Execute the following commands to build a Docker image

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 Copy code

Execute docker images to view the image just built

Excuting an order

  • mvn clean package docker:build: only execute the build operation
  • mvn clean package docker:build -DpushImage Push the image after executing the build
  • mvn clean package docker:build -DpushImageTag executes the build and pushes the image of the specified tag

Note: At least one imageTag must be specified here, it can be configured in the POM or specified on the command line .

The command line is specified as follows:

mvn clean package docker:build -DpushImageTags -DdockerImageTags=imageTag_1 -DdockerImageTags=imageTag_2 , the configuration specified in the POM file is as follows:

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

Bind Docker commands to all stages of Maven

  • You can bind Docker commands to all stages of Maven. We can divide Docker into build, tag, and push, and then bind the package and deploy stages of Maven respectively.

  • You only need to execute mvn deploy to complete the entire build, tag, and push operations. When we execute mvn build, only the build and tag operations are completed .

  • In addition, when we want to skip some steps or only perform a certain step, we don't need to modify the POM file, we only need to specify a certain step to skip docker. For example, when our project has already configured the automation template, but this time we only need to mirror to the local self-test.

  • If you don't want to execute the push phase, you can skip the push operation by specifying the parameter -DskipDockerPush at this time.

In the above example, when we execute mvn package, we execute build and tag operations, and when we execute mvn deploy, we execute build, tag, and push operations. If we want to skip a certain process in docker, we only need to:

  • -DskipDockerBuild skip build image
  • -DskipDockerTag skip tag mirroring
  • -DskipDockerPush skip the push image
  • -DskipDocker skips the entire stage

For example: when we want to execute the package, skip the tag process, then mvn package -DskipDockerTag is needed.

<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> Copy code

The docker-maven-plugin plug-in also provides a lot of useful configuration, just list a few parameters.

Security authentication configuration

When we push the image to the Docker warehouse, whether it is public or private, security authentication is often required, and the operation can be performed after the login is completed. Of course, we can use the command line

docker login -u user_name -p password docker_registry_host
Log in, but it is not very convenient for automated processes. Using the docker-maven-plugin plug-in, we can easily implement security authentication .

1. add the relevant server configuration in the Maven configuration file setting.xml, which mainly configures the Docker registry user authentication information .

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

Then just use the server id in pom.xml.

<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> Copy code

Use private Docker warehouse address

In the actual working environment, we need to push the image to our private Docker warehouse. It is also easy to implement using the dock-maven-plugin plug-in. There are several ways to achieve it :

Modify POM file imageName operation

<configuration> <imageName>{privateImageHubUrl}/imageName/tag</imageName> ... </configuration> Copy code

Just output in the above format.

Modify the newName operation in the POM file

<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> Copy code

Restart the Docker service

systemctl stop docker systemctl start docker Copy code

Open the Docker build port of the firewall

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