Use GitHub Container Registry (GHCR) to host your Helm Charts

3 min read

737 words

TLDR: Full commands can be found at the end of the post.

Update - 14 February 2023: Added command to pull the hosted Helm chart. Pull from GHCR

I recently started to check out Helm and thought about the combination of hosting the charts on GitHub Container Registry (GHCR) since the charts follow the regular OCI (Open Container Image) standard which is also used by Docker container images. Because of that, I tried to understand the steps necessary to host my charts on GHCR since public charts / containers are free of charge. The following post will describe the necessary steps that are required. So let’s dive right in.


First of all, make sure that you have Helm installed in a version >3.8 since OCI support before that is experimental. It is possible to use the feature before 3.8 with the environmental variable HELM_EXPERIMENTAL_OCI=1 set. If you don’t have Helm installed yet you can do so via brew install helm on macOS. For different operating systems please check Helm’s docs for more installation options [1].

For presentation purposes, I will use the default chart created by Helm which is the result of running helm create <chart-name>. For this post, I will call it helm create example-chart. The content of the created directory is not the subject of this post but more information can be found in the Helm docs [2].

To package it all up and make it ready for pushing to GHCR Helm provides the helm package command which takes the argument of the directory to package. In the chart’s parent directory. So using helm package example-chart will create a new package with the name of example-chart-0.1.0.tgz. The version number can be changed in example-chart/Chart.yaml under the version attribute.

GitHub Container Registry Preparation

To push to GitHub Container Registry we need to authenticate with a Personal Access Token. If you never created one you can follow the steps described here [3]. Make sure that your Token has the following permissions:

  • read:packages
  • write:packages
  • delete:packages

You can eather just export your Access Token for the terminal session and use export GHCR_PAT=ghp_... with your Token after the = sign or use your .zshrc or .bashrc. To do so, edit your file with e.g. nano .zshrc and add the export line in your file. The one you need depends on your current default shell. To see which one is your default use echo $SHELL in your terminal. After saving and closing the editor via ctrl + x and confirming with y you have to reload your .zshrc with source .zshrc. After that, the Token should be available for use.

Logging in

To check if things are working use echo $GHCR_PAT | docker login -u <GITHUB-USERNAME> --password-stdin with your username following the -u flag. If everything is configured correctly you should get the answer of Login Succeeded.

Push to GHCR

Pushing now is easy. Get the current chart version and use Helm to push to GHCR:

export CHART_VERSION=$(grep 'version:' ./example-chart/Chart.yaml | tail -n1 | awk '{ print $2}')
helm push example-chart-${CHART_VERSION}.tgz oci://

You should get something similar like the following:

Digest: sha256:c13e9bc40b48460a7b3af6a5df78b4faeff6af7d0688333124884117478be18c

Now your package is pushed and you can check it out via your profile under the tab packages. For example, this example chart can be found here.

This is how you can host your Helm charts on GitHub’s Container Registry.

Pull from GHCR

helm pull oci://

The output will look similar to:

Digest: sha256:e643b697ba7049ab46019d5f142116aa69a36a35595decd5ad7bc0b72d598310

Thank you for reading,

TLDR commands

helm create <chart-name>
helm package <chart-name>
echo $GHCR_PAT | docker login -u <GITHUB-USERNAME> --password-stdin
export CHART_VERSION=$(grep 'version:' ./path/to/Chart.yaml | tail -n1 | awk '{ print $2 }')
helm push <chart-name>-${CHART_VERSION}.tgz oci://<GITHUB-USERNAME>

  1. Installing Helm ↩︎

  2. Helm | Getting Started ↩︎

  3. Authenticating to the Container registry ↩︎