Product: Semarchy Data Platform

Version: 1.3.0 or later

Author: Hélène Zosym


Need

To deploy an SDP Self-Hosted in an air-gapped environment (without an outbound Internet access from Kubernetes cluster) it is required to first mirror the SDP helm chart and required images from the Semarchy Harbor repository to your local repository. While you can retrieve the list of the items to mirror manually, it's an error-prone process. This article describes how to automate the process end to end using the mirroring script and values overlay published in Semarchy's ps-public-artifacts repository, and how to wire that automation into a CI pipeline so it can be re-run for every new chart version. It is intended for infrastructure and platform teams preparing a self-hosted, air-gapped SDP deployment. 


Summarized Solution

  • Authenticate to both the Semarchy source registry and your local target registry before running anything.
  • Run mirror-semarchy-chart.sh, which pulls the chart, renders it with helm template to discover every image reference, copies each image with skopeo, and pushes the chart to your registry.
  • Repoint the deployment values using values.customer-mirrored-images.yaml — three settings cover all twenty images: global.image.registry, plus two hard-coded overrides for dm.secretManager and reloader.
  • Create an image pull secret in the target namespace and reference it from the values file.
  • Install the platform from your local registry and verify with a helm template grep that no image still points at registry.na.semarchy.net.
  • Wrap the whole flow in a CI pipeline (an Azure DevOps example is provided) so a new chart version can be mirrored on demand, with a --dry-run mode to review the plan first.


Detailed Solution


1. Deliverables and Prerequisites 


The repository provides two files that do all the work:

FilePurpose
mirror-semarchy-chart.shMirrors the chart and all of its images to your registry.
values.customer-mirrored-images.yamlDeployment values that repoint every image to your registry.
azure-pipelines.yml(optional)Azure DevOps pipeline that runs the login and mirror steps on demand.


Required on the machine or CI runner that performs the mirroring:

RequirementNotes
helm 3.8+Needs OCI support for pull/push against OCI registries.
skopeoPerforms the actual image copy, all architectures included.
Network accessTo bothregistry.na.semarchy.net and your local registry — this step happens outside the air gap.
CredentialsFor both the Semarchy source registry and the target registry.

On the target Kubernetes cluster: a namespace for the platform, and an image pull secret for the local registry (created in Step 4 below).


2. Running scripts to mirror charts and images

Step 1: Log in to Both Registries

The script assumes both logins already exist before it runs. Both are written to the Helm registry config, which the script then hands to skopeo via --authfile so images authenticate with the same credentials.


# Source (Semarchy) — credentials provided by Semarchy
helm registry login registry.na.semarchy.net \
  --username "$SEMARCHY_USER" --password "$SEMARCHY_KEY"

# Target (your local registry)
helm registry login artifactory.company.com \
  --username "$LOCAL_USER" --password "$LOCAL_KEY"


Step 2: Run the mirroring script

./mirror-semarchy-chart.sh \
  --target-repo   artifactory.company.com/semarchy \
  --chart-version 1.3.0

--target-repo is the base path in your registry under which everything is stored. Images keep their original path underneath it: 

registry.na.semarchy.net/semarchy-release/docker-dm:1.12.1
  ->  artifactory.company.com/semarchy/semarchy-release/docker-dm:1.12.1

What the script automates

  1. helm pull the chart — the parent .tgz bundles all sub-charts, so one push mirrors the whole chart tree.
  2. helm template the chart with all components enabled and extract every image: reference — this render is the authoritative image list, since values.yaml alone does not expose tags or third-party/sub-chart images.
  3. skopeo copy --all each image (all architectures) to the target registry.
  4. helm push the chart .tgz to the target registry.


FlagDefaultDescription
-t, --target-reporequiredTarget registry base, e.g. artifactory.company.com/semarchy.
-v, --chart-versionrequiredChart version to mirror, e.g. 1.3.0.
-s, --source-registryregistry.na.semarchy.netSource image registry.
--source-chart-repooci://<source>/semarchyOCI repo holding the chart.
--chart-target-repooci://<target-repo>Where to push the chart.
-f, --valuesExtra values file for the render (repeatable). Pass your real deployment values for an exact image match.
--authfileHelm registry configAuth file handed to skopeo.
--dry-runoffPrints every planned action without pulling, copying, or pushing.


Run once with --dry-run to review the full plan — chart pull, every image copy, and the chart push — before mirroring for real.


3. Preparing your deployment

Step 1: Repoint the Deployment Values


Open values.customer-mirrored-images.yaml and replace the placeholders. The mirroring is driven by three settings:

global:
  image:
    registry: '<YOUR_LOCAL_REGISTRY>'   # same value as --target-repo above
    repository: 'semarchy-release'      # keep as-is — the mirror preserves this path

dm:
  secretManager:
    image:
      repository: '<YOUR_LOCAL_REGISTRY>/semarchy-release/docker-secret-manager'

reloader:
  image:
    repository: '<YOUR_LOCAL_REGISTRY>/semarchy-release/mirror/stakater/reloader'


global.image.registry repoints 18 of the 20 images by itself. dm.secretManager and reloader hard-code the source registry in the chart and do not honor global.image.registry, so they are overridden explicitly — these two are the only per-component image overrides required. 


Note: Set global.image.registry to the exact same base passed as --target-repo in Step 2 of the previous chapter so the paths line up. Also replace the remaining starter placeholders — <YOUR_GLOBAL_DOMAIN>, <YOUR_LICENSE_KEY_HERE>, <YOUR_INGRESS_CLASS_NAME>, the TLS secret names, the admin user fields, and <YOUR_LOCAL_REGISTRY_PULL_SECRET>.


Step 2: Create the Image Pull Secret

Installation now pulls from your registry, so create a pull secret in the release namespace and reference it — the values file already wires it via global.imagePullSecrets

kubectl create secret docker-registry local-registry \
  --docker-server=artifactory.company.com \
  --docker-username="$LOCAL_USER" \
  --docker-password="$LOCAL_KEY" \
  --namespace=semarchy

Use --docker-server=<host only> (no path). The secret name (local-registry here) must match global.imagePullSecrets[0].name in the values file. 


Step 3: Verify the Mirroring

Confirm no image reference still points at the source registry: 

helm template sdp \
  oci://artifactory.company.com/semarchy/semarchy-data-platform \
  --version 1.3.0 -f values.customer-mirrored-images.yaml \
  | grep -E '^\s*-?\s*image:' | sort -u

Every line returned should reference your local registry, with no occurrence of registry.na.semarchy.net

You have now successfully mirrored the Semarchy Data Platform on your articatory for an air gapped deployment. 

You can proceed with the installation and configuration according to the official documentation.


4. List of the Mirrored Images

These twenty images are copied by the script for chart 1.3.0 (tags change per chart version). All land under <YOUR_LOCAL_REGISTRY>/…:

#Image path (under the mirror base)Repointed by
1semarchy-release/alpine-toolsglobal.image.registry
2semarchy-release/docker-billing-serviceglobal.image.registry
3semarchy-release/docker-dmglobal.image.registry
4semarchy-release/docker-dm-passiveglobal.image.registry
5semarchy-release/docker-log-explorerglobal.image.registry
6semarchy-release/docker-log-explorer-serviceglobal.image.registry
7semarchy-release/docker-secret-managerdm.secretManager.image
8semarchy-release/docker-site-adminglobal.image.registry
9semarchy-release/docker-user-profileglobal.image.registry
10semarchy-release/docker-welcomeglobal.image.registry
11semarchy-release/docker-well-known-serviceglobal.image.registry
12semarchy-release/iam_kc_extensionsglobal.image.registry
13semarchy-release/iam_kc_themesglobal.image.registry
14semarchy-release/sdp-infra-toolsglobal.image.registry
15semarchy-release/mirror/adorsys/keycloak-config-cliglobal.image.registry
16semarchy-release/mirror/eclipse-temuringlobal.image.registry
17semarchy-release/mirror/envoyproxy/envoyglobal.image.registry
18semarchy-release/mirror/fluent/fluent-bitglobal.image.registry
19semarchy-release/mirror/keycloak/keycloakglobal.image.registry
20semarchy-release/mirror/stakater/reloaderreloader.image

 

5. (Optional) Automating with CI

An Azure DevOps pipeline that performs the login and mirror steps is provided as azure-pipelines.yml. It runs manually (trigger: none), takes the chart version and target repo as run-time parameters, and pulls registry credentials from a secret variable group — nothing sensitive is stored in the pipeline file itself.

One-time setup

  1. In Azure DevOps: Pipelines > Library > + Variable group, name it semarchy-mirror-creds.
  2. Add SRC_HELM_USER, SRC_HELM_KEY, TGT_HELM_USER, TGT_HELM_KEY and mark each as secret.
  3. Pipeline > Edit and link the semarchy-mirror-creds variable group.
  4. Commit mirror-semarchy-chart.sh at the repo root (or adjust scriptPath).

At queue time, the pipeline prompts for:

ParameterDefaultPurpose
chartVersionrequiredChart version to mirror, e.g. 1.3.0.
targetReporequiredTarget registry repo (host/path), e.g. artifactory.corp.com/semarchy.
sourceRegistryregistry.na.semarchy.netSource image registry host.
dryRunfalsePlan only, copy nothing — useful to validate a new chart version first.

The pipeline installs Helm and skopeo on an ubuntu-latest agent, logs in to both registries using a shared HELM_REGISTRY_CONFIG auth file, then invokes mirror-semarchy-chart.sh with the supplied parameters.


6. Upgrading to a New Chart Version

Image tags are tied to the chart version, so for every new release:

  1. Re-run Step 2 of chapter 2 (or the CI pipeline) with the new --chart-version to mirror the new chart and any new or updated images.
  2. Confirm the image set with the script's --dry-run output - if Semarchy adds or renames an image, it appears here first. 
  3. Check that now images are flagged by Semarchy in release notes as requiring manual overwrite


7. Known Limitations and Troubleshooting

SymptomLikely cause / fix
unauthorized during pullNot logged in to the source registry - redo Step 1.1.
skopeo auth failuresThe auth file passed to skopeo doesn't hold both logins. Ensure both helm registry login calls ran, or pass --authfile <path> explicitly.
Pods stuck ImagePullBackOffPull secret missing or misnamed, or global.image.registry doesn't match --target-repo. Check chapter 3.
An image still points at registry.na.semarchy.netA newly added hard-coded image in a chart update. Re-run the verify command, then add a matching per-component image.repository override.
license.body must be set on renderProvide a real (or any non-placeholder) license value.


8. Mirroring Checklist

Action
Install and verify helm (3.8+) and skopeo on the mirroring machine or CI runner.
Log in to the Semarchy source registry and the target local registry.
Run mirror-semarchy-chart.sh --dry-run and review the plan.
Run the script for real with the correct --target-repo and --chart-version.
Set global.image.registry in the values overlay to the same base as --target-repo.
Override dm.secretManager.image.repository and reloader.image.repository.
Replace all remaining <YOUR_...> placeholders in the values file.
Create the image pull secret in the release namespace and match its name to global.imagePullSecrets[0].name.
Run the verification script
Run the helm template | grep image: verification — confirm zero references to registry.na.semarchy.net.
Wire the mirror script into CI (e.g. the provided Azure DevOps pipeline) with credentials in a secret variable group.
Document the re-mirroring procedure for future chart upgrades.