Problem
Teams publish images to one registry, either GHCR (via builder) or the OpenShift internal registry (via BuildConfigs), and their deployments pull from it at runtime. Whichever registry they use becomes a runtime dependency: if it's unreachable, every pod restart, scale-up and CronJob run fails with ImagePullBackOff, even though nothing was being deployed.
- GHCR-only images fail on Silver when GHCR or GitHub is degraded. bcgov/wps hit this risk with an image that moved to GHCR and gained a manual-only fallback.
- OpenShift-only images can't be pulled outside the cluster, so local development, outside contributors and other clusters have to rebuild.
Builds themselves already depend on GitHub (triggers, git clone), so the gap is redundancy for pulls, not builds. bcgov/wps currently mirrors by hand with oc image mirror in bcgov/wps#5899.
Proposal
A mirror action that copies a built image between GHCR and the OpenShift registry, in either direction, and is called right after the build:
- Copy by digest, both directions. GHCR →
image-registry.apps.<cluster>.devops.gov.bc.ca/<namespace>/<image>:<tag>, or the reverse. The destination digest must match the sourcethe identical image.
- Keep multi-arch indexes intact. Copy the whole manifest list (e.g.
oc image mirror --keep-manifest-list, or skopeo copy --all) instead of picking one platform. Document whey and ImageStreams accept manifest lists (importMode: PreserveOriginal).
- Never block a deploy. A failed mirror raises acceeds, since the primary copy already exists. Opt-instrict mode for teams that want it to fail.
- Handle OpenShift auth. Take a token or servicee registry immediately before the copy. Short-livedTokenRequest tokens can expire during a long build.
- Document the deploy side. Deployments pull frory by default, with a single image parameter to switch to the mirror during an outage.
Acceptance
Problem
Teams publish images to one registry, either GHCR (via
builder) or the OpenShift internal registry (via BuildConfigs), and their deployments pull from it at runtime. Whichever registry they use becomes a runtime dependency: if it's unreachable, every pod restart, scale-up and CronJob run fails withImagePullBackOff, even though nothing was being deployed.Builds themselves already depend on GitHub (triggers,
git clone), so the gap is redundancy for pulls, not builds. bcgov/wps currently mirrors by hand withoc image mirrorin bcgov/wps#5899.Proposal
A
mirroraction that copies a built image between GHCR and the OpenShift registry, in either direction, and is called right after the build:image-registry.apps.<cluster>.devops.gov.bc.ca/<namespace>/<image>:<tag>, or the reverse. The destination digest must match the sourcethe identical image.oc image mirror --keep-manifest-list, orskopeo copy --all) instead of picking one platform. Document whey and ImageStreams accept manifest lists (importMode: PreserveOriginal).Acceptance
packages: write, OpenShift push access to the target namespace) and the deploy-side switch for outagesoc image mirrorsteps with the action