Ping Identity Devops

Build a Docker Product Image Locally

This page describes the process to build a Docker image of our products with the build tools found in our Docker Builds repository and a local copy of a product zip archive.

Product images are built on Ping-provided parent images (pingidentity/pingbase-java, published on Docker Hub) that bundle the operating system and the Java runtime. The parent images are pulled automatically during the build; you do not need to build any foundational layers yourself.

For a video demonstration of this process, visit this link.

Cloning a build repository

Open a terminal and clone the pingidentity-docker-builds repo:

git clone https://github.com/pingidentity/pingidentity-docker-builds.git

Download a product .zip archive

  1. Go to Product Downloads and download the product to be used to build a Docker image.

    Ensure you download the product distribution .zip archive and not the Windows installer.

  2. When the download has finished, rename the file to product.zip:

    mv pingfederate-13.1.3.zip product.zip
  3. Move product.zip to the Build Directory.

    In the pingidentity-docker-builds repository directory for each product, move the product.zip file to the <product>/tmp directory, where /<product> is the name of one of our available products. For example:

    mv ~/Downloads/product.zip \
       ~/pingidentity/devops/pingidentity-docker-builds/pingfederate/tmp

    Building from product.zip adds the -fsoverride tag suffix to the resulting image, indicating it was built from a local archive.

Build the Docker image

Before building the image, examine the versions.json file in the product directory. You must specify a valid version for the build script. Since the product .zip archive is being provided, it does not matter which version you select as long as it is listed. The build scripts use this file for validating builds, so it has to find a match from this file. For example, you can see that 13.1.3 is one option that can be used for building a PingFederate image:

{
    "latest": "13.1.3",
    "versions": [
        {
            "version": "13.1.3",
            "preferredShim": "alpine:3.24.2",
            "shims": [
                {
                    "shim": "alpine:3.24.2",
                    "preferredJVM": "al25",
                    "jvms": [
                        {
                            "jvm": "al25",
                            "build": true,
                            "deploy": true,
                            "registries": [
                                "DockerHub",
                                "Artifactory"
                            ]
                        }
                    ]
                },

The shim selects the base operating system flavor: alpine:3.24.2 builds on the pingbase-java:alpine3.24 parent image, and redhat/ubi9-minimal:9.8-…​ builds on the pingbase-java:ubi9 parent image. The jvm id (al25 above) selects the Java runtime — JDK 17, 21, or 25 — bundled in the parent image. For most cases, accept the preferred values and do not pass any shim or JVM options.

  1. Go to the base of the pingidentity-docker-builds repo. For example:

    cd ~/pingidentity/devops/pingidentity-docker-builds
  2. Run the build_product.sh script with the appropriate options. For example:

    ./ci_scripts/build_product.sh \
        --product pingfederate \
        --version 13.1.3

    The parent image (pingbase-java) is pulled from Docker Hub automatically if it is not already present on your system. To pre-pull the parent image explicitly (for example, in an air-gapped or proxy-only environment), use:

    docker pull pingidentity/pingbase-java:alpine3.24-jdk25

    When the build is completed, the product image is displayed. For example:

    REPOSITORY                     TAG                                                          IMAGE ID    CREATED         SIZE
    pingidentity/pingfederate      13.1.3-fsoverride-alpine_3.24.2-al25-<branch>-<sha>-x86_64   <id>        7 seconds ago   759MB

    The image tag follows the pattern <version>-fsoverride-<shim>-<jvm>-<branch>-<git-sha>-<arch>, where the shim has / and : characters replaced by underscores, and the trailing <branch>-<git-sha> reflects the git branch and commit of the build repository you cloned.

It is important to build from the base of the repository as shown in the example.

Building all products locally

To build all products locally, you will need the .zip file for each (renamed to product.zip) in the appropriate directory. When configured, run build_product.sh for each product directory. Versions, shims, and JVMs resolve from each product’s versions.json. For example:

for p in apache-jmeter ldap-sdk-tools pingaccess pingauthorize pingauthorizepap \
         pingcentral pingdataconsole pingdatasync pingdelegator pingdirectory \
         pingdirectoryproxy pingfederate pingtoolkit; do
    ci_scripts/build_product.sh --product "$p" || break
done

Re-tagging the local image

To change the tag of the created image and push it to your own Docker registry, use the docker tag command:

docker tag [image id] \
  [Docker Registry]/[Organization]/[Image Name]:[tag]

For example:

docker tag 404a2b14df0c \
  gcp.io/pingidentity/pingfederate:localbuild
# Display new tag
docker image ls
# Output snippet
pingidentity/pingfederate            13.1.3-fsoverride-alpine_3.24.2-al25-<branch>-<sha>-x86_64   <id>   4 minutes ago   759MB
gcp.io/pingidentity/pingfederate     localbuild