Skip to main content
In this walkthrough you’ll use Flux’s Source Controller to pull an OCI artifact from an OCI registry (GitHub Container Registry / GHCR) and deploy it with a Kustomization. The demo pulls the bb-app image from GHCR, configures authentication for a private registry, creates an OCIRepository source, and deploys the manifests produced by that artifact.
A GitHub user profile/packages page in dark mode with a large circular avatar on the left and a list of two private packages on the right. The avatar shows a smiling person.
Prerequisites
  • A Kubernetes cluster with Flux installed (source-controller and kustomize-controller).
  • Access to the private GHCR repository and a GitHub personal access token with package read scope.
  • flux CLI and kubectl configured to your cluster.
  • (Optional) cosign or other supply-chain tooling if you prefer digest-based references.
Quick local test Pull the image locally to confirm the image/tag exist:
Step 1 — Create an OCIRepository (Flux source) From your cluster repo (example: flux-clusters/dev-cluster) use the flux CLI to create an OCIRepository resource and export the YAML:
This generates an OCIRepository resource (Flux’s source type for OCI registries). Replace the --tag placeholder with the exact tag or digest you want to track. Example exported YAML:
Find the exact tag or digest You can copy the tag/digest from the registry UI or from the docker pull output. For this demo:
  • Tag: 7.7.0-0bb2691
  • Digest: sha256:379024c535859545876ae260f5a2367f8b34a758528fc6074d58c8ec9fbbf28c
Tip: If you use signed images (cosign), referencing the digest is preferred for stronger immutability guarantees. Step 2 — Create registry credentials for Flux Flux requires a registry secret so the source-controller can authenticate to GHCR. Use flux to create a Kubernetes dockerconfigjson secret:
Replace --username and --password with your registry username and personal access token. Alternatively you can create a standard kubernetes.io/dockerconfigjson secret yourself. Verify the secret exists in flux-system:
Example output:
Resource summary Step 3 — Create the Kustomization to deploy the manifests Create a Kustomization that references the OCIRepository source. This demo uses a few useful options:
  • healthChecks — instructs Flux to verify rollout/health status of specific resources.
  • dependsOn — make this Kustomization wait for other Kustomizations (e.g., infra) to be ready.
  • timeout — maximum wait time for health checks.
Kustomization YAML used in this demo:
If your OCI artifact is private, ensure the referenced OCIRepository includes a secretRef pointing to a registry secret in the flux-system namespace (or adjust namespaces so the secret is visible to the source-controller).
Health check examples
  • Check a Deployment rollout:
  • Check HelmRelease objects (Flux Helm support):
dependsOn usage Use dependsOn when an application requires infra resources (databases, secrets) to be present before deployment:
Commit and push Commit the OCIRepository, ghcr-auth secret (if exported), and the Kustomization YAML to your Git repo so Flux picks them up. Reconciliation and debugging
  1. Check Kustomization status via Flux:
Example output when reconciliation starts:
  1. If the Kustomization is Unknown or stalled, inspect the resource status in Kubernetes to get health check messages:
Look for status conditions messages such as:
Common health check issue If a health check times out, verify the exact resource name and namespace listed in healthChecks. Matching is literal — any mismatch prevents Flux from locating the resource. In this demo the initial health check referenced the wrong Deployment name; updating it to block-buster-7-7-0 fixed the timeout.
  1. After fixing the health check, trigger reconciliation or wait for automatic reconcile:
Successful status example:
  1. Validate resources in the target namespace:
Example output:
Verify the app in the browser Open the application URL (NodePort / Ingress) and confirm the version deployed. This demo intentionally includes a bug where the new “high score” value is not persisted; that will be addressed in a later release.
A browser screenshot of a block-breaker arcade game showing rows of multicolored bricks, a paddle and ball at the bottom, plus score and level indicators. A small "Game Over" alert popup is visible near the top.
Wrap-up You have now:
  • Created an OCIRepository source that points to an OCI artifact in GHCR.
  • Configured a registry secret so Flux can pull private OCI artifacts.
  • Created a Kustomization to deploy manifests from the OCI source.
  • Used healthChecks and dependsOn to control rollout order and verify deployment health.
  • Troubleshot common reconciliation and health check issues.
Further reading

Watch Video