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 withhelm templateto discover every image reference, copies each image withskopeo, 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 fordm.secretManagerandreloader. - 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 templategrep that no image still points atregistry.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-runmode to review the plan first.
Detailed Solution
1. Deliverables and Prerequisites
The repository provides two files that do all the work:
| File | Purpose |
|---|---|
mirror-semarchy-chart.sh | Mirrors the chart and all of its images to your registry. |
values.customer-mirrored-images.yaml | Deployment 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:
| Requirement | Notes |
|---|---|
helm 3.8+ | Needs OCI support for pull/push against OCI registries. |
skopeo | Performs the actual image copy, all architectures included. |
| Network access | To bothregistry.na.semarchy.net and your local registry — this step happens outside the air gap. |
| Credentials | For 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
helm pullthe chart — the parent.tgzbundles all sub-charts, so one push mirrors the whole chart tree.helm templatethe chart with all components enabled and extract everyimage:reference — this render is the authoritative image list, sincevalues.yamlalone does not expose tags or third-party/sub-chart images.skopeo copy --alleach image (all architectures) to the target registry.helm pushthe chart.tgzto the target registry.
| Flag | Default | Description |
|---|---|---|
-t, --target-repo | required | Target registry base, e.g. artifactory.company.com/semarchy. |
-v, --chart-version | required | Chart version to mirror, e.g. 1.3.0. |
-s, --source-registry | registry.na.semarchy.net | Source image registry. |
--source-chart-repo | oci://<source>/semarchy | OCI repo holding the chart. |
--chart-target-repo | oci://<target-repo> | Where to push the chart. |
-f, --values | — | Extra values file for the render (repeatable). Pass your real deployment values for an exact image match. |
--authfile | Helm registry config | Auth file handed to skopeo. |
--dry-run | off | Prints 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 |
|---|---|---|
| 1 | semarchy-release/alpine-tools | global.image.registry |
| 2 | semarchy-release/docker-billing-service | global.image.registry |
| 3 | semarchy-release/docker-dm | global.image.registry |
| 4 | semarchy-release/docker-dm-passive | global.image.registry |
| 5 | semarchy-release/docker-log-explorer | global.image.registry |
| 6 | semarchy-release/docker-log-explorer-service | global.image.registry |
| 7 | semarchy-release/docker-secret-manager | dm.secretManager.image |
| 8 | semarchy-release/docker-site-admin | global.image.registry |
| 9 | semarchy-release/docker-user-profile | global.image.registry |
| 10 | semarchy-release/docker-welcome | global.image.registry |
| 11 | semarchy-release/docker-well-known-service | global.image.registry |
| 12 | semarchy-release/iam_kc_extensions | global.image.registry |
| 13 | semarchy-release/iam_kc_themes | global.image.registry |
| 14 | semarchy-release/sdp-infra-tools | global.image.registry |
| 15 | semarchy-release/mirror/adorsys/keycloak-config-cli | global.image.registry |
| 16 | semarchy-release/mirror/eclipse-temurin | global.image.registry |
| 17 | semarchy-release/mirror/envoyproxy/envoy | global.image.registry |
| 18 | semarchy-release/mirror/fluent/fluent-bit | global.image.registry |
| 19 | semarchy-release/mirror/keycloak/keycloak | global.image.registry |
| 20 | semarchy-release/mirror/stakater/reloader | reloader.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
- In Azure DevOps: Pipelines > Library > + Variable group, name it
semarchy-mirror-creds. - Add
SRC_HELM_USER,SRC_HELM_KEY,TGT_HELM_USER,TGT_HELM_KEYand mark each as secret. - Pipeline > Edit and link the
semarchy-mirror-credsvariable group. - Commit
mirror-semarchy-chart.shat the repo root (or adjustscriptPath).
At queue time, the pipeline prompts for:
| Parameter | Default | Purpose |
|---|---|---|
chartVersion | required | Chart version to mirror, e.g. 1.3.0. |
targetRepo | required | Target registry repo (host/path), e.g. artifactory.corp.com/semarchy. |
sourceRegistry | registry.na.semarchy.net | Source image registry host. |
dryRun | false | Plan 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:
- Re-run Step 2 of chapter 2 (or the CI pipeline) with the new
--chart-versionto mirror the new chart and any new or updated images. - Confirm the image set with the script's
--dry-runoutput - if Semarchy adds or renames an image, it appears here first. - Check that now images are flagged by Semarchy in release notes as requiring manual overwrite
7. Known Limitations and Troubleshooting
| Symptom | Likely cause / fix |
|---|---|
unauthorized during pull | Not logged in to the source registry - redo Step 1.1. |
skopeo auth failures | The auth file passed to skopeo doesn't hold both logins. Ensure both helm registry login calls ran, or pass --authfile <path> explicitly. |
Pods stuck ImagePullBackOff | Pull secret missing or misnamed, or global.image.registry doesn't match --target-repo. Check chapter 3. |
An image still points at registry.na.semarchy.net | A 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 render | Provide 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. |