Publish Java Application Image to External Registry on Red Hat OpenShift

(Posted by Rohan Kumar on 15/12/2023 tagged openshift java maven image )

Introduction:

I came across this blog post a few days ago: Pushing Application Images to External Registry . It showcases how you can push to some external container registry changing output OpenShift’s BuildConfig. Writing a blog post about it from a Java developer’s perspective sounded like a nice idea to me. Since I’m talking about Java developer experience, I’m going to use Eclipse JKube again to simplify this scenario.

We are going to build a container image in Red Hat OpenShift and push that image to an external container registry (Quay.io in our case) using OpenShift Maven Plugin.

Prerequisites:

You would need the following things to be able to follow this article:

Setting up Application:

You can either use an existing project or create a new one. I would be creating a simple Quarkus Application from Quarkus Starter. Select your preferred project groupId, artifactId, and Java version, and download and unpack the zip file.

Open the pom.xml and add Eclipse JKube’s OpenShift Maven Plugin in <plugins> section:

<plugin>
      <groupId>org.eclipse.jkube</groupId>
      <artifactId>openshift-maven-plugin</artifactId>
      <version>1.15.0</version>                                                              
</plugin>

Now we should be able to use OpenShift Maven Plugin in our project.

Adding Registry Credentials as OpenShift Secret:

Once you’ve logged into your OpenShift cluster, you need to add Registry authentication credentials as Secret into it.

You can do that by issuing this command:

$ oc create secret docker-registry \ 
  --docker-server=quay.io          \ 
  --docker-username=$QUAY_USERNAME \ 
  --docker-password=$QUAY_PASSWORD \ 
  quay-secret                       
secret/quay-secret created

Configuring OpenShift Maven Plugin to Push Image to Quay.io

Default behavior of OpenShift Maven Plugin is to build and push the container image to OpenShift’s internal registry. In order to override this behavior, we need to provide some configuration. We will add <configuration> section in the plugin declaration to override build type, OpenShift secret to use during OpenShift Build, and image name.

  <plugin>
    <groupId>org.eclipse.jkube</groupId>
    <artifactId>openshift-maven-plugin</artifactId>
    <version>1.15.0</version>
    <configuration>
        <!-- (1) -->
        <buildOutputKind>DockerImage</buildOutputKind>
        <!-- (2) -->
        <openshiftPushSecret>quay-secret</openshiftPushSecret>
        <generator>
          <config>
            <quarkus>
              <!-- (3) -->
              <name>quay.io/${env.QUAY_USERNAME}/${project.artifactId}:${project.version}</name>
            </quarkus>
          </config>
        </generator>
    </configuration>
  </plugin>
  1. buildOutputKind instructs to use DockerImage as output instead of ImageStreamTag
  2. openshiftPushSecret specified the secret to use while doing OpenShift build.
  3. Eclipse JKube has a concept of generators to build opinionated container images for well known Java frameworks. This configuration instructs JKube to override the default name of image (group/artifact:version) to quay.io/username/projectName:version.

Building and Pushing Image to Quay.io

Once you’ve configured the plugin as per your requirements, you can go ahead and issue OpenShift Maven Plugin build goal. This would build a container image and push it to a specified external registry (quay.io in our case).

$ mvn package oc:build

You will notice that during Image is pushed as a last step in OpenShift Maven Plugin Build Logs:

[INFO] oc: Pushing image quay.io/username/quarkus-openshift-quay-image-push:1.0.0-SNAPSHOT ...
[INFO] oc: Pushed 0/3 layers, 1% complete
[INFO] oc: Pushed 1/3 layers, 76% complete
[INFO] oc: Pushed 2/3 layers, 89% complete
[INFO] oc: Pushed 3/3 layers, 100% complete
[INFO] oc: Push successful
[INFO] oc: Build quarkus-openshift-quay-image-push-s2i-5 in status Complete

Conclusion:

In this blog post, you learned how you can leverage on OpenShift Maven Plugin to seamlessly publish your application’s container image to a remote external registry from within your OpenShift cluster. You can also watch this video by my colleague Marc Nuri which showcases this in action:

You can find code related to this blog post in this GitHub Repository.

To learn more about Eclipse JKube, check these links: