Skip to content

This is a maven plugin that retags the Docker images that are used by a project, to a project specific name.

License

Notifications You must be signed in to change notification settings

CAFapi/docker-versions-maven-plugin

Repository files navigation

Docker Versions Maven Plugin

This is a maven plugin that retags the Docker images that are used by a project, to a project specific name.
The project specific name can then be used in place of the actual Docker image name.

Goals overview

The docker-versions plugin has the following goals.

  • docker-versions:populate-project-registry
  • docker-versions:depopulate-project-registry
  • docker-versions:use-latest-releases
  • docker-versions:help

populate-project-registry

Retags the Docker images that are used by a project, to a project specific name.

Required Parameters

Name Type Description
<repository> String The repository and name of the docker image in the format <repository>/<name>.
<tag> String The docker image tag.

Optional Parameters

Name Type Description
<digest> String The digest value of docker image. It will be used to ensure that the correct image is being tagged.
<skipPull> boolean If `true` the image is expected to be in the registry and no attempt will be made to pull it. It is `false` by default.
<targetRepository> String This string will be used in the project specific name tag instead of the repository value.

depopulate-project-registry

Removes the project specific name tag from the Docker images that are used by a project.

Required Parameters

Name Type Description
<repository> String The repository and name of the docker image in the format <repository>/<name>.

Optional Parameters

Name Type Description
<targetRepository> String This string will be used in the project specific name tag instead of the repository value.

use-latest-releases

Replaces any Docker image release version with the latest static version of the image in the plugin configuration.
This goal will not replace versions of images configured without a digest, such as images with SNAPSHOT, latest, stable or dynamic tags.

Required Parameters

Name Type Description
<repository> String The repository and name of the docker image in the format <repository>/<name>.
<tag> String The docker image tag.

Optional Parameters

Name Type Description
<latestTag> String This is the tag that the version will be updated to. If it is not specified the image will be updated to the `latest` tag.

help

Displays the help information.

Adding the plugin to the build

Using this plugin in build could be done in multiple ways.

The simplest way is to add the plugin to the build with required configuration and define it as an extension. The plugin's LifecycleParticipant will automatically include the populate-project-registry and depopulate-project-registry based on the maven phases and goals being executed.

The plugin configuration could include the <projectDockerRegistry> parameter to specify the project registry:

<projectDockerRegistry>${project.name}-${project.version}.project-registries.local</projectDockerRegistry>

Example snippet of plugin entry with minimal required configuration in build:

<plugin>
    <groupId>com.github.cafapi.plugins.docker.versions</groupId>
    <artifactId>docker-versions-maven-plugin</artifactId>
    <version>2.0.0-SNAPSHOT</version>
    <extensions>true</extensions>
    <configuration>
        <projectDockerRegistry>${project.name}-${project.version}.project-registries.local</projectDockerRegistry>
        <imageManagement>
            <image>
                <repository>${dockerHubPublic}/cafapi/opensuse-jre17</repository>
                <tag>1.4.3</tag>
                <digest>sha256:76b8dc916151a5ede5d8a999fcd0929ca3cd3a9dbf67085f65ef98b5279359f4</digest>
            </image>
            <image>
                <repository>${dockerHubPublic}/cafapi/prereleases</repository>
                <targetRepository>cafapi/opensuse-tomcat-jre17</targetRepository>
                <tag>opensuse-tomcat-jre17-2.0.0-SNAPSHOT</tag>
            </image>
        </imageManagement>
    </configuration>
</plugin>

Example log output when plugin kicks in:

  • mvn clean install
[INFO] Scanning for projects...  
[INFO] Adding docker version management goals... [docker-versions:populate-project-registry, clean, install, docker-versions:depopulate-project-registry]  
...  

The plugin's lifecycle participant added both populate-project-registry and depopulate-project-registry to be executed at the start and end of the mvn execution respectively.

  • mvn validate site
[INFO] Scanning for projects...  
[INFO] Inspecting build with total of 20 modules...  
[INFO] Installing Nexus Staging features:  
[INFO]   ... total of 20 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin  
[INFO] ------------------------------------------------------------------------  
[INFO] Reactor Build Order:  
...  

In this case the plugin's lifecycle participant did not add any docker-version goals to the mvn execution, since the tasks being executed do not need them.

In case more control is needed, it can be manually configured with the executions bound to required phases.
The <projectDockerRegistry> will need to be set as a pom property instead of the plugin configuration parameter. <projectDockerRegistry> value can only have alphabets (a-z) (A-Z), digits (0-9), minus sign (-), and period (.).

<plugin>
    <groupId>com.github.cafapi.plugins.docker.versions</groupId>
    <artifactId>docker-versions-maven-plugin</artifactId>
    <version>2.0.0-SNAPSHOT</version>
    <executions>
        <execution>
            <id>populate-project-registry</id>
            <phase>initialize</phase>
            <goals>
                <goal>populate-project-registry</goal>
            </goals>
        </execution>
        <execution>
            <id>depopulate-project-registry</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>depopulate-project-registry</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <imageManagement>
            <image>
                <repository>${dockerHubPublic}/cafapi/opensuse-jre17</repository>
                <tag>1.4.3</tag>
                <digest>sha256:76b8dc916151a5ede5d8a999fcd0929ca3cd3a9dbf67085f65ef98b5279359f4</digest>
            </image>
            <image>
                <repository>${dockerHubPublic}/cafapi/prereleases</repository>
                <targetRepository>cafapi/opensuse-tomcat-jre17</targetRepository>
                <tag>opensuse-tomcat-jre17-2.0.0-SNAPSHOT</tag>
            </image>
        </imageManagement>
    </configuration>
</plugin>

Note

If the plugin configuration is defined in the aggregator pom of a multi-module project, the configuration will be inherited by the sub projects. When the plugin goals are run, they will be executed for all the projects which is not necessary. In this case the plugin goals can be run in a non-recursive way by specifying the maven -N option, like,

mvn -N docker-versions:populate-project-registry

or

mvn -N -Ddocker.ignore.versions=/tmp/ignoreDockerVersions.yaml docker-versions:use-latest-releases

The Maven plugin will pull the images if necessary, and then retag them into the project registry that is specified by the property.

Source code references to:

${dockerHubPublic}/cafapi/opensuse-jre17:1

would be updated to reference the version from the project-specific registry instead:

${projectDockerRegistry}/cafapi/opensuse-jre17:latest

Source code references to:

${dockerHubPublic}/cafapi/prereleases:opensuse-tomcat-jre17-2.0.0-SNAPSHOT

would be updated to reference the version from the project-specific registry instead:

${projectDockerRegistry}/cafapi/opensuse-tomcat-jre17

Note: The version need not be specified when referencing images in the project-specific registry. This means that only the plugin configuration needs to be updated to update the Docker image versions.

Authentication

The authentication information for the docker registries is looked up two places in this order:

  1. From the Maven settings stored typically in ~/.m2/settings.xml
  2. From the Docker settings stored in ~/.docker/config.json

The following properties are read:

  • username: User to authenticate
  • password: Password to authenticate
  • email: Optional email address which is sent to the registry
  • auth: Optional base64 encoded 'username:password' string, which can be set instead of username and password

Configuration

The docker host url can be set in any of these ways:

  • docker.host property
  • dockerHost plugin configuration
  • DOCKER_HOST environment variable

Http connection timeout can be set in the plugin configuration. This configuration is optional and the values indicate time in seconds.

<httpConfiguration>
    <connectionTimout>30</connectionTimout>
    <responseTimout>45</responseTimout>
    <downloadImageTimout>100</downloadImageTimout>
</httpConfiguration>

When using the use-latest-releases goal an optional ignoreVersions configuration can be added. When finding the latest static tag for the image any tag that matches the regex or the exact value specified will be ignored. Image name patterns can be added to the <images> list if the regex or the exact value to be ignored has to be applied only to specific images.
<ignoreVersion> without an <images> list will be applied to all images.

<ignoreVersions>
    <ignoreVersion>
        <type>regex</type>
        <version>(?i).*alpha.*</version>
    </ignoreVersion>
    <ignoreVersion>
        <type>exact</type>
        <version>3.8.26-alpine</version>
    </ignoreVersion>
    <ignoreVersion>
        <type>regex</type>
        <version>(?i).*-alpine.*</version>
        <images>
            <image>(?i).*rabbitmq.*</image>
            <image>(?i).*maven.*</image>
            <image>(?i).*haproxy.*</image>
        </images>
    </ignoreVersion>
    <ignoreVersion>
        <type>regex</type>
        <version>(?!1\.7\.1$).*</version>
        <images>(?i).*mesosphere/mesos-.*</images>
    </ignoreVersion>
</ignoreVersions>

Another way to configure images tags that should be ignored is by setting ignoreVersionsConfigPath.
This is the path of a yaml file containing the image tags to ignore. If both ignoreVersions and ignoreVersionsConfigPath are set the configured values will be combined.

<ignoreVersionsConfigPath>/tmp/ignoreDockerVersions.yaml</ignoreVersionsConfigPath>

The path to the yaml config file can also be set as a user property called docker.ignore.versions.

mvn -Ddocker.ignore.versions=/tmp/ignoreDockerVersions.yaml docker-versions:use-latest-releases -N

Example yaml file containing the image tags to ignore:

- type: regex
  version: (?i).*alpha.*
- type: regex
  version: (?i).*beta.*
- type: regex
  version: (?i).*-rc.*
- type: regex
  version: (?i).*alpine.*
- type: regex
  version: (?i).*-bullseye.*
  images:
  - (?i).*postgres.*
  - (?i).*haproxy.*
- type: regex
  version: (?!7\.10\.2-amd64$).*
  images:
  - (?i).*elasticsearch/elasticsearch-oss.*

The following configuration options can be set via environment variables.

Name Description
DOCKER_HOST The Docker Host URL, e.g. tcp://localhost:2376 or unix:///var/run/docker.sock.
DOCKER_TLS_VERIFY Enable/disable TLS verification (switch between http and https protocol).
DOCKER_CERT_PATH Path to the certificates needed for TLS verification.
DOCKER_CONFIG Path for additional docker configuration files (like .dockercfg).
CONNECTION_TIMEOUT_SECONDS Determines the timeout until a new connection to DOCKER_HOST is fully established, default is 30s.
RESPONSE_TIMEOUT_SECONDS Determines the timeout until arrival of a response from the DOCKER_HOST, default is 45s.
DOWNLOAD_IMAGE_TIMEOUT_SECONDS Determines the timeout for an image pull to be completed, default is 300s.

Skipping goals

The execution of the plugin or any of its goals can be skipped by setting any these properties to true:

  • docker.versions.skip: Skips executution of the plugin entirely
  • skipPopulateProjectRegistry: Skips executution of the populate-project-registry goal
  • skipDepopulateProjectRegistry: Skips executution of the depopulate-project-registry goal
  • skipUseLatestReleases: Skips executution of the use-latest-releases goal
<plugin>
    <groupId>com.github.cafapi.plugins.docker.versions</groupId>
    <artifactId>docker-versions-maven-plugin</artifactId>
    <version>2.0.0-SNAPSHOT</version>
    <extensions>true</extensions>
    <configuration>
        <skip>true</skip>
        <projectDockerRegistry>${project.name}-${project.version}.project-registries.local</projectDockerRegistry>
        <imageManagement>
            <image>
                <repository>${dockerHubPublic}/cafapi/opensuse-jre17</repository>
                <tag>1.4.3</tag>
                <digest>sha256:76b8dc916151a5ede5d8a999fcd0929ca3cd3a9dbf67085f65ef98b5279359f4</digest>
            </image>
            <image>
                <repository>${dockerHubPublic}/cafapi/prereleases</repository>
                <targetRepository>cafapi/opensuse-tomcat-jre17</targetRepository>
                <tag>opensuse-tomcat-jre17-2.0.0-SNAPSHOT</tag>
            </image>
        </imageManagement>
    </configuration>
</plugin>

You can also skip the goal execution via the command line by setting the skip configuration property:

mvn -DskipDepopulateProjectRegistry=true install

About

This is a maven plugin that retags the Docker images that are used by a project, to a project specific name.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages