Use GitHub Container Registry (GHCR) to host your Helm Charts
Tags: devops, kubernetes, github
Published: 2022-05-08 20:14:29

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

I recently started to check out [Helm](https://helm.sh) and thought about the combination of hosting the charts on [GitHub Container Registry (GHCR)](https://ghcr.io) 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.

## Helm

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 ghcr.io -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:

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

You should get something similar like the following:

```
Pushed: ghcr.io/niklasmtj/example-chart:0.1.0
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 under https://github.com/users/niklasmtj/packages/container/package/example-chart.

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

Thank you for reading, 
Niklas

## TLDR commands

```bash
helm create <chart-name>
helm package <chart-name>
echo $GHCR_PAT | docker login ghcr.io -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://ghcr.io/<GITHUB-USERNAME>
```

[^1]: https://helm.sh/docs/intro/install/
[^2]: https://helm.sh/docs/chart_template_guide/getting_started/
[^3]: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-to-the-container-registry