on
Hands-on with Helm: package and distribute your charts as OCI artifacts
Kubernetes packaging has been moving fast: Helm charts are no longer confined to index.yaml-hosted repositories. Today, storing charts as OCI artifacts in container registries is a practical, well-supported pattern that simplifies distribution, integrates with container workflows, and better fits modern CI/CD pipelines. This hands-on guide shows why OCI-based Helm charts matter, and walks through packaging, pushing, installing, and (optionally) signing charts for production use.
Why this matters now
- Helm added stable OCI support in Helm 3.8.0, so modern Helm users get OCI features by default. (helm.sh)
- Many upstream projects and vendors already publish charts as OCI artifacts (for example, Bitnami switched their charts to default to OCI distribution). (blog.bitnami.com)
- Cloud registries and providers are deprecating legacy Helm repository support in favor of OCI (Azure Container Registry, for example, announced retirement timelines for legacy Helm repos; if you host charts in such registries, you should migrate). (learn.microsoft.com)
What you’ll learn
- Prerequisites and quick checklist
- Package a chart and push it to an OCI registry (commands)
- Install from an OCI registry
- CI/CD example (GitHub Actions)
- Optional: sign and verify charts (cosign / provenance)
- Migration and troubleshooting tips
Prereqs and quick checklist
- Helm CLI (>= v3.8.0 recommended). OCI support is enabled by default in 3.8+. (helm.sh)
- An OCI-compliant registry you can push to (GHCR, Docker Hub, Google Artifact Registry, Azure Container Registry, Harbor, ECR, etc.). Most support Helm chart artifacts. (cloud.google.com)
- Registry credentials (PAT, service account, or other auth method) and permissions to push packages.
Step 1 — create and package a chart If you already have a chart directory, skip the create step.
Create a sample chart:
helm create myapp
# edit Chart.yaml, templates/, values.yaml as needed
Package the chart into a .tgz archive (Helm uses Chart.yaml name & version to name the file):
helm package myapp
# produces myapp-0.1.0.tgz (assuming version 0.1.0 in Chart.yaml)
The packaged .tgz is what Helm will push to the OCI registry. (cloud.google.com)
Step 2 — login and push the chart to an OCI registry Authenticate your Helm client to the registry. Example: GitHub Container Registry (GHCR) or any other OCI endpoint. Helm exposes a registry login command:
# interactive password prompt
helm registry login ghcr.io -u <USER>
# or use stdin to avoid interactive prompt (example with GitHub Actions PAT)
echo $GITHUB_TOKEN | helm registry login ghcr.io -u $GITHUB_USER --password-stdin
Push the packaged chart:
helm push myapp-0.1.0.tgz oci://ghcr.io/<OWNER>/helm-charts
Helm will push the chart as an OCI artifact and print the pushed image ref and digest. The same push flow works with Artifact Registry, Harbor, ACR, GCR, etc. (help.cloudsmith.io)
Step 3 — install a chart directly from an OCI registry You don’t need to “helm repo add” for OCI charts. Install or upgrade directly using the oci:// reference:
# install a specific version
helm install myrelease oci://ghcr.io/<OWNER>/helm-charts/myapp --version 0.1.0
# or upgrade (install if missing)
helm upgrade --install myrelease oci://ghcr.io/<OWNER>/helm-charts/myapp --version 0.1.0
If the registry requires authentication, ensure you’ve run helm registry login first. Many official projects now recommend installing from their OCI registry. (Example: cert-manager points users to their OCI chart location.) (cert-manager.io)
CI/CD: automate packaging and pushing (GitHub Actions example) A common pattern is to package and publish charts on release/tag events. Here’s a minimal GitHub Actions job snippet (conceptual):
name: Publish Helm chart
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Helm
uses: azure/setup-helm@v3
- name: Get tag
id: tag
run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Login to GHCR
run: echo "$" | helm registry login ghcr.io -u $ --password-stdin
- name: Package and push
run: |
helm package ./charts/myapp --version $ --app-version $
helm push myapp-$.tgz oci://ghcr.io/$/helm-charts
This pattern ties chart versions to Git tags and publishes to the same container registry you might already use for images. Real pipelines should include linting, chart tests, and security checks before publishing. Example CI patterns are used in multiple public projects and blog examples. (xenitab.github.io)
Optional: sign and verify charts for integrity and supply-chain trust
- Helm has longstanding support for provenance files (GPG-based .prov files) and the –verify flag during install for traditional chart repositories. (helm.sh)
- For OCI-stored charts, modern workflows use Sigstore/cosign to sign and verify OCI artifacts (signing the chart image digest in the registry). Tools and patterns exist to sign a pushed chart with cosign and verify it before installation (useful for GitOps controllers like Flux/ArgoCD that support verification). When using cosign, remember OCI-tag naming differences (Helm changes + to _ in tags) and prefer signing by digest for immutability. (docs.cloudbees.com)
Simple cosign workflow (conceptual)
# after helm push, capture digest (helm prints it)
CHART_REF=ghcr.io/<OWNER>/helm-charts/myapp@sha256:<DIGEST>
# sign the digest (keyless or key-backed)
cosign sign $CHART_REF
# verify
cosign verify $CHART_REF
Work with your GitOps tooling to require verification on deploy (Flux and ArgoCD have verification options that can use cosign). (wiki.jmehan.com)
Migration notes and practical tips
- If you maintain a public chart repository (index.yaml) or host charts in legacy registry formats, plan migration. Many vendors are already moving to OCI by default (Bitnami, cert-manager, etc.), and cloud providers have announced timelines for retiring legacy Helm repo support in their registries (Azure ACR deprecated legacy Helm repositories and set timelines for removal of non-OCI charts). Check your target registry’s deprecation/migration docs and plan accordingly. Be explicit about dates in your migration plan. (blog.bitnami.com)
- Names and versions: Helm maps chart name -> image name and chart version -> tag when pushing to OCI. Avoid plus signs in tags (Helm substitutes + with _) or be prepared for minor differences in tooling (cosign compatibility notes apply). (docs.cloudbees.com)
- Visibility: OCI registries (GHCR, Docker Hub) may default to private packages; update package visibility or use proper access tokens for consumers. (trstringer.com)
- Tooling: GitOps controllers and artifact registries have varying levels of OCI Helm support—verify compatibility with your chosen registry and controller. Many popular tools already support OCI charts. (securecodebox.io)
Troubleshooting quick hits
- Authentication errors: double-check helm registry login credentials and any token scopes (write/push for publishing; read for installs).
- Cannot find chart when installing: ensure you included the chart name (not the tgz file) and the –version you pushed. Use helm pull with oci://… to verify you can download the chart. (cloud.google.com)
- Tag/digest mismatches with verification: cosign works best against digests; sign the digest reported by helm push, not a tag, to avoid surprises. (tech.aabouzaid.com)
Wrap-up — when to use OCI-distributed charts Use OCI for charts when you want:
- Unified artifact storage (images and charts in one registry)
- Simpler CI pipelines that already push images to container registries
- Better integration with container-based security (signatures, immutability)
- To follow upstream project recommendations and avoid legacy repo deprecation issues
If you maintain charts today, try a local end-to-end proof: package a chart, push to an OCI registry you control, install it on a cluster, and add a simple publish job to your CI. The commands in this article are the core steps you’ll repeat across registries; the larger work is operationalizing signing, access control, and CI tests.
References and further reading
- Helm docs, OCI topics (OCI support enabled by default in Helm 3.8.0). (helm.sh)
- Google Cloud Artifact Registry Helm guide (package / push / install examples). (cloud.google.com)
- Bitnami: moving charts to OCI (announcement and guidance). (blog.bitnami.com)
- Azure Container Registry Helm deprecation and migration notes (dates and migration guidance). (learn.microsoft.com)
- Helm provenance & signing overview and notes on OCI workflows with Sigstore/Cosign. (helm.sh)
If you want, I can:
- Produce a ready-to-run GitHub Actions workflow tailored to your repo and registry (GHCR, GCR, ACR, etc.).
- Help convert an existing chart repo to OCI and create a migration checklist for your users.