Configure a Mirror Registry for In-Dataplane Builds¶
When WSO2 Developer Platform runs builds inside a private data plane (PDP) using Argo Workflows, every build step pulls container images and downloads language packages from public sources (Docker Hub, Google Buildpacks registry, npm, Maven Central, PyPI, NuGet, RubyGems, Composer, etc.). On restricted or air-gapped clusters where direct egress to these public sources is blocked, the build will fail at the image pull or dependency resolution step.
To support these environments, WSO2 Developer Platform lets a platform engineer redirect every outbound build dependency through a mirror registry of your choice — for example, an internal Nexus, Harbor, JFrog Artifactory, or any OCI-compliant proxy — by mounting a single Kubernetes Secret into the build pod. The build then transparently pulls images and packages from your mirror instead of the public source.
Info
This feature is available only on private data planes that run the in-dataplane build system on Argo Workflows. It does not apply to WSO2 Developer Platform cloud data plane builds.
How it works¶
During each build, WSO2 Developer Platform mounts a Kubernetes Secret named choreo-build-registry-proxy into the build pod at /mnt/proxy-config (read-only, optional). Build scripts read configuration values from this directory before fetching anything from the network:
- Container images are rewritten so that pulls go to the configured OCI mirror instead of the public source, or replaced entirely with a customer-supplied image reference.
- Language package managers (npm, Maven, Gradle, NuGet, PyPI, Go, RubyGems, Composer) are reconfigured at the start of the build to fetch dependencies from the configured proxy URLs.
If the Secret is not present, the mounted directory is empty and the build proceeds with the default public sources, so the feature is fully opt-in and backwards compatible.
Key lookup precedence¶
For every configuration key, the build script first looks for a build-strategy-specific override and then falls back to a global value:
<strategy>.<key>— applies only to that build strategy (for example,buildpack.pkg-npm-url).<key>— applies to all build strategies (for example,pkg-npm-url).
The build strategies recognized by the lookup are buildpack, ballerina, mi, webapp, prism, test-runner, and byoc.
Prerequisites¶
Before you configure the mirror registry, ensure the following:
- The PDP is configured to run in-dataplane builds on Argo Workflows.
- You have
kubectlaccess to the build namespace on the PDP cluster. - Your mirror registry (Nexus, Harbor, JFrog, or equivalent) is reachable from the build cluster and is configured with proxy repositories for each public source you want to mirror.
- Any credentials required by your mirror (basic auth username/password or token) are available.
Step 1: Identify the values you need¶
Decide which sources you want to redirect. Most restricted clusters need entries for the following:
- OCI container image mirrors — for base images used by the build (Docker Hub, Choreo private registry, Google Cloud Buildpacks registry).
- Language package proxies — for the package manager(s) used by your component (npm, Maven, Gradle, NuGet, PyPI, Go, RubyGems, Composer).
- (Optional) Full image overrides — when you cannot mirror a public image and instead want the build to use a different image you have already pushed to your own registry.
The full key reference is in the Configuration reference section below.
Step 2: Create the choreo-build-registry-proxy Secret¶
Create the Secret in the same namespace as the in-dataplane build workloads. Use one file per key, where the file name is the key and the file content is the value. For example:
mkdir -p ./proxy-config
echo -n "nexus.example.com/dockerhub-proxy" > ./proxy-config/oci-dockerhub-url
echo -n "build-user" > ./proxy-config/oci-dockerhub-username
echo -n "<password>" > ./proxy-config/oci-dockerhub-password
echo -n "https://nexus.example.com/repository/npm-proxy/" > ./proxy-config/pkg-npm-url
echo -n "<npm-token>" > ./proxy-config/pkg-npm-token
echo -n "https://nexus.example.com/repository/maven-proxy/" > ./proxy-config/pkg-maven-url
echo -n "build-user" > ./proxy-config/pkg-maven-username
echo -n "<password>" > ./proxy-config/pkg-maven-password
kubectl -n <build-namespace> create secret generic choreo-build-registry-proxy \
--from-file=./proxy-config
To restrict a value to a single build strategy, prefix the key with the strategy name and a dot. For example, to point only Ballerina builds at a Ballerina-specific Maven proxy:
echo -n "https://nexus.example.com/repository/ballerina-maven/" \
> ./proxy-config/ballerina.pkg-maven-url
Note
Keys are read as plain text. Do not URL-encode credentials or wrap values in quotes — the build script trims trailing newlines, but does not unescape anything else.
Step 3: Trigger a build and verify¶
After the Secret is in place, trigger a build for a component on the PDP and confirm in the CI pipeline logs that:
- Image pulls reference your mirror host instead of
docker.io,gcr.io/buildpacks, orchoreocontrolplane.azurecr.io. - Package manager output (npm, Maven, etc.) shows requests going to your proxy URLs.
- The build completes successfully.
If the build fails at an image pull or dependency download step, see Troubleshooting.
Configuration reference¶
All keys are optional. Only define the ones you need. Strategy-scoped overrides (<strategy>.<key>) always take precedence over the corresponding global key.
OCI container image mirrors¶
Use these keys when you want to mirror an entire public OCI registry behind a single proxy host. The build rewrites the registry portion of every image reference to the configured mirror URL.
| Key | Mirrors | Notes |
|---|---|---|
oci-dockerhub-url, oci-dockerhub-username, oci-dockerhub-password |
Docker Hub (index.docker.io) |
When set, the build skips the default Docker Hub login. |
oci-choreo-url, oci-choreo-username, oci-choreo-password |
The WSO2 Developer Platform private registry that hosts nginx, Prism, and Go base images. | |
oci-buildpacks-url, oci-buildpacks-username, oci-buildpacks-password |
The Google Cloud Buildpacks registry (builder, lifecycle, run images). |
Full image overrides¶
Use these keys when mirroring is not enough — for example, when your security policy requires a customer-built golden image. The value can be either a complete image reference (registry/repo:tag or registry/repo@sha256:...) or a registry/repo prefix; in the latter case, the original tag or digest is preserved.
| Key | Replaces |
|---|---|
image-node-ref |
Node.js base image used by webapp and test-runner builds |
image-nginx-ref |
Nginx image used to serve webapp builds |
image-prism-ref |
Prism image used by Prism mock builds |
image-golang-ref |
Go image used by Prism mock builds |
image-buildpacks-run-ref |
Buildpacks run image |
image-buildpacks-lifecycle-ref |
Buildpacks lifecycle image |
image-buildpacks-builder-ref |
Buildpacks builder image |
Language package proxies¶
Use these keys to redirect language package managers to your mirror. Where applicable, supply credentials with the matching -username/-password keys (or -token for npm).
| Key | Package manager | Credentials |
|---|---|---|
pkg-npm-url, pkg-npm-token |
npm | Token only |
pkg-maven-url, pkg-maven-username, pkg-maven-password |
Maven | Optional basic auth |
pkg-gradle-url, pkg-gradle-username, pkg-gradle-password |
Gradle | Optional basic auth |
pkg-nuget-url, pkg-nuget-username, pkg-nuget-password |
NuGet | Optional basic auth |
pkg-python-url, pkg-python-username, pkg-python-password |
PyPI | Optional basic auth |
pkg-go-url, pkg-go-username, pkg-go-password |
Go module proxy | Optional basic auth |
pkg-composer-url, pkg-composer-username, pkg-composer-password |
PHP Composer | Optional basic auth |
pkg-rubygems-url, pkg-rubygems-username, pkg-rubygems-password |
RubyGems | Optional basic auth |
Support matrix per build strategy¶
Not every build strategy consumes every key. The following table summarizes which keys take effect for each strategy:
| Build strategy | OCI mirrors | Image overrides | Package proxies |
|---|---|---|---|
| Buildpack | oci-dockerhub-url, oci-choreo-url, oci-buildpacks-url |
image-buildpacks-run-ref, image-buildpacks-lifecycle-ref, image-buildpacks-builder-ref |
npm, Maven, Gradle, NuGet, PyPI, Go, Composer, RubyGems |
| Ballerina | oci-buildpacks-url |
image-buildpacks-run-ref, image-buildpacks-lifecycle-ref, image-buildpacks-builder-ref |
Maven, Gradle, NuGet, PyPI, Go, Composer, RubyGems |
| MI | oci-buildpacks-url |
image-buildpacks-lifecycle-ref, image-buildpacks-builder-ref |
Maven |
| Webapp | oci-dockerhub-url, oci-choreo-url |
image-node-ref, image-nginx-ref |
npm |
| Prism mock | oci-choreo-url |
image-prism-ref, image-golang-ref |
— |
| Test Runner | oci-dockerhub-url |
image-node-ref |
npm |
| BYOC (Dockerfile) | oci-dockerhub-url |
— | — |
Domain allowlisting (alternative to a forward proxy)¶
Some customers prefer not to introduce a mirror registry at all, and instead allow direct egress to the public sources used by the build. In that case the same outbound destinations still apply — only the routing changes. The list of domains that must be reachable depends on the build strategies you use, including:
- Docker Hub (
index.docker.io,registry-1.docker.io,auth.docker.io,production.cloudflare.docker.com) - Google Cloud Buildpacks (
us-docker.pkg.dev/gae-runtimes/runtimes-ubuntu2204/*,gcr.io/buildpacks/*) - The WSO2 Developer Platform private registry (
choreocontrolplane.azurecr.ioor the PDP-specific ACR) - Language package managers:
registry.npmjs.org,repo.maven.apache.org,services.gradle.org,api.nuget.org,pypi.org/files.pythonhosted.org,proxy.golang.org/sum.golang.org,rubygems.org,repo.packagist.org - Ballerina Central (
api.central.ballerina.io,fileserver.central.ballerina.io,dist.ballerina.io) - GitHub release CDN (
release-assets.githubusercontent.com) for SDK and JDK downloads
Contact WSO2 Developer Platform support for the exact, up-to-date allowlist that applies to the build strategies you have enabled.
Troubleshooting¶
- Build cannot pull an image from your mirror. Verify that the mirror URL in the Secret does not include a scheme (
https://) — OCI registry hosts are bare hostnames. Confirm that the configured credentials authenticate from inside the build cluster (podman loginfrom a debug pod). podman loginfails forindex.docker.ioon a restricted cluster. Make sureoci-dockerhub-urlis set. When this key is present the build skips the default Docker Hub login; when it is absent, the build will attempt to log in to Docker Hub and fail on clusters where it is blocked.- Package manager still hits the public registry. Confirm the Secret is mounted (
kubectl get pod <build-pod> -o yaml | grep proxy-config) and that the key uses the correct name and namespace. Strategy-scoped keys (<strategy>.<key>) only apply to the listed strategy — set the global key as well if you want the same value used everywhere. - Webapp build pulls Node 18 even though a different version is selected in the console. Set
image-node-refto your golden Node image. Without an explicit override, an OCI mirror cannot change the Node version that the webapp build pins.