> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Push Helm Chart to OCI Registry

> Guide to package a Helm chart, authenticate to an OCI registry, push the chart as an OCI artifact, and verify the published package.

This guide shows how to package a Helm chart and publish it as an OCI artifact to an OCI-compatible registry (example: GitHub Container Registry, `ghcr.io`). The steps follow the repository's `7-demo` branch and use the `7.7.1` subfolder, which contains a Helm chart.

Repository folder layout under `7.7.1`:

```bash theme={null}
root ~/bb-app-source  7-demo
➜ tree 7.7.1
7.7.1
├── helm-chart
│   ├── Chart.yaml
│   ├── templates
│   │   ├── NOTES.txt
│   │   ├── _helpers.tpl
│   │   ├── deployment.yaml
│   │   └── service.yaml
│   └── values.yaml
└── src
    ├── Dockerfile
    ├── highscore.php
    ├── images
    │   ├── level1.png
    │   └── level2.png
    ├── index.php
    └── level2.php

4 directories, 12 files
```

Goal: create an OCI artifact from the Helm chart and push it to an OCI registry, then verify the published package.

## Prerequisites

| Requirement | Notes / Example |
| - | - |
| Helm installed | Example used here: `Helm v3.11.2` |
| OCI-compatible registry | Example: `ghcr.io` (GitHub Container Registry) |
| Registry authentication token | For GitHub, a Personal Access Token with `write:packages` and `read:packages` scopes |

Confirm Helm is installed:

```bash theme={null}
root ~/bb-app-source  🔍  7-demo
➤➤ helm version
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/batman/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/batman/.kube/config
version.BuildInfo{Version:"v3.11.2", GitCommit:"912ebc1cd10d38d340f048efaf0abda047c3468e", GitTreeState:"clean", GoVersion:"go1.18.10"}
```

## Step 1 — Package the Helm chart

Use `helm package` to create a compressed chart archive (`.tgz`) from the chart directory. This produces a distributable chart file you can upload to an OCI registry.

Example:

```bash theme={null}
root ~/bb-app-source  7-demo
➜ helm package 7.7.1/helm-chart/
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/batman/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/batman/.kube/config
Successfully packaged chart and saved it to: /home/batman/bb-app-source/block-buster-helm-app-7.7.1.tgz
```

If you prefer the Helm native OCI workflow, you can instead use `helm chart save` to create an OCI-ready reference before pushing.

## Step 2 — Authenticate to the OCI registry

Log in to the OCI registry before pushing artifacts. For GitHub Container Registry (`ghcr.io`), use your GitHub username and a Personal Access Token (PAT) as the password.

For GitHub Container Registry, ensure your Personal Access Token includes package permissions such as `write:packages` and `read:packages`. Also consider enabling the package visibility settings on GitHub if you want public or private distribution.

Example login:

```bash theme={null}
root ~/bb-app-source  7-demo
➜ helm registry login ghcr.io --username sidd-harth-2
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/batman/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/batman/.kube/config
Password:
Login Succeeded
```

## Step 3 — Push the packaged chart to the OCI registry

There are two common ways to push Helm charts to an OCI registry:

* Use Helm's native OCI support (Helm v3.8+): `helm chart save` + `helm chart push`, or `helm chart push`.
* Use the community `helm-push` plugin which provides `helm push`.

The example below shows using the `helm-push` plugin (command: `helm push`). If you prefer Helm's native OCI commands, replace `helm push` with `helm chart push` or use the `chart save`/`chart push` sequence.

Example push with `helm-push`:

```bash theme={null}
root ~/bb-app-source  7-demo
➜ helm push block-buster-helm-app-7.7.1.tgz oci://ghcr.io/sidd-harth-2/bb-app
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/batman/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/batman/.kube/config
Pushed: ghcr.io/sidd-harth-2/bb-app/block-buster-helm-app:7.7.1
Digest: sha256:87a7cb7863786349f9379faa843cd07c7b2f862fd295191285eacd089ff10e6a
```

After success, the chart artifact is published under your registry namespace (for example: `ghcr.io/sidd-harth-2/bb-app`) and tagged with the chart version (e.g., `7.7.1`).

## Step 4 — Verify the published package

You can verify the published package in two ways:

* Registry UI: Check GitHub Packages → your repository → Packages to confirm the package name and version appear.
* Helm CLI: Pull the chart back with Helm to confirm it was stored as a Helm OCI artifact.

Helm pull example (fetches the chart archive):

```bash theme={null}
$ helm pull oci://ghcr.io/sidd-harth-2/bb-app/block-buster-helm-app --version 7.7.1
```

If you used Helm's native OCI commands, you can also:

```bash theme={null}
$ helm chart pull ghcr.io/sidd-harth-2/bb-app/block-buster-helm-app:7.7.1
$ helm chart export ghcr.io/sidd-harth-2/bb-app/block-buster-helm-app:7.7.1
```

Note: Many registries store Helm charts as OCI artifacts with Helm-specific media types. These artifacts may not always be pulled using standard Docker CLI commands, so prefer using Helm for pull/export operations.

## Quick reference — Common commands

| Purpose | Command |
| -: | - |
| Package Helm chart | `helm package 7.7.1/helm-chart/` |
| Login to OCI registry | `helm registry login ghcr.io --username <your-username>` |
| Push using helm-push plugin | `helm push <chart>.tgz oci://ghcr.io/<user>/<repo>` |
| Push using Helm OCI native | `helm chart push ghcr.io/<user>/<repo>/<chart>:<version>` |
| Pull chart with Helm | `helm pull oci://ghcr.io/<user>/<repo>/<chart> --version <version>` |
| Native OCI pull/export | `helm chart pull ghcr.io/<user>/<repo>/<chart>:<version>` / `helm chart export ...` |

## Summary

* Package the chart with `helm package` (or use `helm chart save` for the native OCI flow).
* Authenticate to the OCI registry with `helm registry login`.
* Push the packaged chart using either Helm's native OCI commands (`helm chart push`) or the `helm-push` plugin (`helm push`) to an `oci://` URL.
* Verify the chart in the registry UI or pull it back with Helm (`helm pull` / `helm chart pull`).

## Links and references

* [Helm documentation — OCI support](https://helm.sh/docs/topics/registries/)
* [GitHub Packages — Container registry docs](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry)
* [Helm GitHub repo](https://github.com/helm/helm)

That's all for now.

> **[Watch Video](https://learn.kodekloud.com/user/courses/gitops-with-fluxcd/module/205ec7c7-4cb6-4ecb-9bb5-fa50419f1e68/lesson/eb806cb8-3d9f-427f-bf12-058e1f3bd692)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.