Use a different container registry
This guide covers pulling every image the Helm-installed Arcade platform needs from a registry you run, instead of Docker Hub.
When you need it
- Your cluster can’t reach Docker Hub, or your policy requires images from an approved registry.
- You run an air-gapped install.
- You mirror images to avoid Docker Hub rate limits.
Values overlay
There’s no single registry prefix for the whole chart: set each image’s repository to its path in your registry. Copy the images at the tags your chart version uses (see the values reference on Artifact Hub ).
dockerRegistry:
enabled: true
existingSecret: arcade-registry-pull # a kubernetes.io/dockerconfigjson Secret
engine:
image:
repository: registry.example.com/arcadedev/engine
coordinator:
image:
repository: registry.example.com/arcadedev/coordinator
dashboard:
image:
repository: registry.example.com/arcadedev/dashboard
experienceApi:
image:
repository: registry.example.com/arcadedev/experience-api
workerDefaults:
image:
repository: registry.example.com/arcadedev/worker
rbac:
openfga:
image:
repository: registry.example.com/arcadedev/openfga
redis:
image:
repository: registry.example.com/redis
postgres:
image: registry.example.com/postgres:17-alpine
supportImages:
busybox:
repository: registry.example.com/busybox
curl:
repository: registry.example.com/curlimages/curl
postgres:
repository: registry.example.com/postgres
tag: 17-alpine
# Only if Arcade Deploy is enabled
deployments:
image:
repository: arcadedev/runner
registry:
server: registry.example.com
imagePullSecrets: [arcade-registry-pull]Pull credentials
dockerRegistry controls the pull Secret on the Arcade pods:
dockerRegistry.enabled(defaulttrue) adds animagePullSecretsentry to the Arcade component pods (, coordinator, dashboard, Experience API, OpenFGA, workers, and the chart’s Jobs). Leave it on for the privatearcadedev/*images or a registry that needs credentials.dockerRegistry.existingSecretnames a Secret you create in the release namespace, of typekubernetes.io/dockerconfigjson. This is the usual choice for a mirror.- Without
existingSecret, the chart generates a Secret nameddockerRegistry.secretNamefromdockerRegistry.server,dockerRegistry.username, anddockerRegistry.token(a Docker Hub access token).
The bundled PostgreSQL and Redis StatefulSets don’t get a pull Secret. If your mirror requires authentication, they can’t pull from it. Mirror postgres.image and redis.image to a path your nodes can pull without credentials (for example, through node-level registry credentials), or use external PostgreSQL and Redis.
Support images
The init containers use supportImages.busybox (generate-env-file), supportImages.curl (wait-for-workers, which must be a real curl image), and supportImages.postgres (wait-for-db, which needs the psql client). Each has repository, tag, and pullPolicy. An empty supportImages.postgres.repository falls back to postgres.image, so a mirrored postgres.image already covers it.
The Arcade Deploy runner image
If you enable Arcade Deploy, the starts every deployed server from the runner image in the workers namespace:
- The image is
deployments.registry.serverjoined withdeployments.image.repository(defaultarcadedev/runner). Withdeployments.registry.serverempty, the repository is used as-is. Its tag isdeployments.image.tag, or the chart’s app version when that’s empty. - Deployed server pods use the Secrets listed in
deployments.registry.imagePullSecrets. These Secrets must exist in the workers namespace (deployments.namespace), not the release namespace. - When
dockerRegistry.enabledis on anddockerRegistry.existingSecretis empty, the chart also addsdockerRegistry.secretNameto that list. A Secret you name indockerRegistry.existingSecretisn’t added, so list it indeployments.registry.imagePullSecretsand create a copy in the workers namespace.
Air-gapped installs
- Copy every image above, at your chart version’s tags, into your registry. Include the Arcade Deploy runner image if you use Arcade Deploy, and any images your workers list overrides.
- Copy the chart itself (
oci://public.ecr.aws/s5i6x9d1/charts/arcade) into an OCI registry you can reach, and install from there. - Create the pull Secret in the release namespace, and in the workers namespace for Arcade Deploy.
- Install with the overlay above.
Image pulls are only part of an air-gapped install: the identity provider, OAuth providers, and any server dependencies also need to be reachable from inside your network.
Verify it
# Every image comes from your registry
kubectl -n arcade get pods -o jsonpath='{range .items[*]}{range .spec.initContainers[*]}{.image}{"\n"}{end}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' | sort -u
# Pods pulled successfully
kubectl -n arcade get pods
kubectl -n arcade get events --field-selector reason=FailedFor Arcade Deploy, deploy a test server and run the same image check in the workers namespace (arcade-workers by default).
Common failures
| Symptom | Likely cause and fix |
|---|---|
ImagePullBackOff on one component | Its image.repository still points at Docker Hub, or the tag isn’t mirrored. Check the pod’s image and mirror the missing tag. |
ImagePullBackOff on init containers | supportImages.* still point at Docker Hub. Override them. |
401 or unauthorized pulling PostgreSQL or Redis | The bundled StatefulSets have no pull Secret. See the warning under Pull credentials. |
401 or unauthorized pulling | The pull Secret is missing, in the wrong namespace, or not kubernetes.io/dockerconfigjson. Check dockerRegistry.existingSecret. |
| Deployed servers fail to pull the runner image | The Secret isn’t in the workers namespace, or isn’t listed in deployments.registry.imagePullSecrets. |
The runner image path is doubled, for example registry.example.com/registry.example.com/... | deployments.image.repository includes the registry host while deployments.registry.server is also set. Set the host in one place. |
What you own and what the chart handles
| You | The chart |
|---|---|
| Running the registry, and mirroring each image at the right tag | Using the repository and tag you set for every image |
| Creating pull Secrets in the release namespace and the workers namespace | Adding imagePullSecrets to Arcade pods when dockerRegistry.enabled |
| Mirroring the chart for air-gapped installs | Generating a pull Secret from dockerRegistry.username and dockerRegistry.token when you don’t bring one |
| Keeping mirrors current on each upgrade | Building the runner image path from deployments.registry.server and passing pull Secrets to deployed servers |