on
Hands-on with Helm: package your charts as OCI artifacts
Helm charts as OCI artifacts are the practical next step for packaging and distributing Kubernetes apps. Over the last few years major chart publishers and cloud registries have been moving from legacy chart repositories (index.yaml + HTTP hosting) to OCI-compliant registries (the same registries that store container images). This matters because many registries and vendors are asking — or forcing — teams to migrate, and using OCI can simplify CI/CD, signing, and single-registry workflows. (blog.bitnami.com)
Why OCI for Helm?
- Single place for images and charts: you can manage images, Helm charts and other OCI artifacts from the same registry and with the same credentials and tooling. (github.com)
- Built-in support in Helm: Helm’s CLI supports pushing/pulling/installing charts to/from OCI registries (GA since Helm 3.8.0). That means no experimental flags in modern Helm clients. (newreleases.io)
- Better automation and signing: OCI artifacts can be signed (cosign/Sigstore) and verified in CI or at deploy time, which improves supply-chain security. Tooling like Flux and ci systems already support verifying OCI-published charts. (cncf.io)
Quick hands-on: package → push → install This mini workflow assumes Helm >= 3.8.0 and access to an OCI registry (ghcr.io, ghcr, ghcr.io/ORG, Azure ACR, Harbor, Quay, etc.).
1) Package the chart
- From your chart folder:
helm package ./mychart # produces mychart-0.1.0.tgz
2) Log in to the registry
- Use Helm’s registry login (works like docker login):
helm registry login ghcr.io -u USERNAME -p $GITHUB_TOKEN
3) Push the packaged chart
- Note the oci:// prefix. For push the basename and tag are inferred from the chart name/version:
helm push mychart-0.1.0.tgz oci://ghcr.io/your-org/helm-charts # output shows the pushed name and the digestHelm’s docs show the push/pull/install subcommands and explain registry URL rules. Some registries require you to create the repository/namespace first. (v3.helm.sh)
4) Install directly from OCI
helm install myrelease oci://ghcr.io/your-org/helm-charts/mychart --version 0.1.0
Sign and verify charts (recommended)
- Use cosign to sign the chart’s digest after push and verify at install time.
- After push you’ll get a chart digest (sha256:…). Sign that digest:
# example: sign the pushed digest cosign sign ghcr.io/your-org/helm-charts/mychart@sha256:... # verify cosign verify ghcr.io/your-org/helm-charts/mychart@sha256:...
- After push you’ll get a chart digest (sha256:…). Sign that digest:
- Projects and docs increasingly recommend or publish signed charts; Flux and verification tooling support this flow. (documentation.suse.com)
Common gotchas and best practices
- Helm version: OCI support is GA in Helm 3.8.0 — older Helm clients may need HELM_EXPERIMENTAL_OCI=1. Use a modern Helm in CI agents. (newreleases.io)
- Registry quirks: Some registries require you to pre-create repositories or namespaces before pushing; error messages can be confusing (HEAD/401). Test pushes in a sandbox registry first. (v3.helm.sh)
- Provider timelines: Some providers have removed or are removing legacy chart-repo support — if you host charts in legacy repositories you may need to migrate or lose those charts. Check provider notices (for example, Azure Container Registry provided migration warnings and deletion dates in their docs). (learn.microsoft.com)
- Signing and provenance: When you sign an OCI chart, best practice is to sign the digest (immutable) not a mutable tag. Use Sigstore/Cosign and publish verification steps in your release docs. (tech.aabouzaid.com)
- Watch Helm client releases: Registry behavior has changed across Helm releases (some users have reported push issues on specific Helm versions vs specific registries — test your exact combo). For example, there are recent issues reported around pushing charts to Quay with newer Helm 3.18.x clients in certain configurations. If you rely on Quay or another self-hosted registry, verify compatibility. (github.com)
Practical checklist before you migrate
- Pick a target registry (GHCR, ACR, GCR/Artifact Registry, Harbor, Quay). Confirm it supports OCI Helm charts and the access model you need. (github.com)
- Upgrade CI agents to Helm >= 3.8.0 (or set HELM_EXPERIMENTAL_OCI for older versions during migration). (docs.azure.cn)
- Add cosign signing into the release pipeline (sign digest after push; keep verification keys in a safe location). (documentation.suse.com)
- Test installs and upgrades from the OCI repo in a staging cluster; validate values, dependencies, and chart.lock behavior.
- Document rollback steps and where artifacts live (digest + tag + verification key).
Closing note Migrating Helm charts to OCI is hands-on but pays off: simpler registry management, stronger signing, and smoother CI/CD. Start with a single chart, test pushes/pulls and cosign verification in a staging pipeline, and get a sense for your registry’s quirks before switching everything over.
If you want, I can:
- produce a ready-to-run GitHub Actions workflow that packages, signs (cosign), and pushes a Helm chart to GHCR or ACR, or
- help you test a sample chart against a specific registry (GHCR, Harbor, Quay, ACR) and tune the workflow for that provider.
Which would be most useful to you next?