The only requirement for a public Helm chart repository is that it exposes a URL named “index.yaml”. So by adding a file named “index.yaml” to source control and enabling Github Pages to serve the file over HTTPS, you have the minimal basis for a public Helm chart repository.
The backing Chart content (.tgz) can also be uploaded as a Github Release, conveniently allowing us to host the entire solution in our Github repository.
The ‘cr‘ (chart-releaser) tool wraps up the logic of managing index.yaml and the backing chart .tgz files, allowing us to focus on chart development.
If you would rather use Github Actions to automatically run chart-releaser on push events, read my article here.
Prerequisites
- Github repository – If you do not already have a Github repository to work with, refer to this section in the Github docs
- Helm – if you have not installed the ‘helm’ tool, follow my instructions here
- Github PAT – to upload Helm Chart .tgz, a Github Personal Access Token (classic) with all permissions to ‘repo’ is required
- Chart Releaser tool – used to generate index.yaml and upload the Chart .tgz files to Github via API
# download, extract, and copy binary to PATH cd ~ wget https://github.com/helm/chart-releaser/releases/download/v1.6.0/chart-releaser_1.6.0_linux_amd64.tar.gz tar xfz chart-releaser_1.6.0_linux_amd64.tar.gz cr sudo mv cr /usr/local/bin/
Helm Chart for publishing
This article (and the default tool settings) assume your Helm Charts are located in the ‘charts’ folder of the github repository.
If you do not have a helm chart in the ‘charts’ folder yet, follow these instructions to create a simple nginx Helm Chart.
# substitute these values for your own Github repository git clone https://github.com/fabianlee/helm-chart-published-to-github.git cd helm-chart-published-to-github # setup variables repo_name="${PWD##*/}" owner_name=$(git remote -v | grep origin | head -n1 | grep -Po ":\K[^/]*") echo "Going to configure $repo_name owned by '$owner_name' as a Helm Chart repository" # create standard 'charts' folder mkdir -p charts cd charts # create simple 'nginx' sample Chart helm create nginx cd .. # dry-run of chart, shows manifests that would be used during release helm install --dry-run mynginx1 charts/nginx
Enable Github Pages feature
By creating a new branch named ‘gh-pages’, it will automatically enable Github Pages and our ability to serve content from the source code repository at ‘https://<owner>.github.io/<repoName>’.
Run the following commands to create a fresh branch named ‘gh-pages’.
# get current branch git branch main_branch=$(git branch --show-current) # create fresh 'gh-pages' branch, standard for Github Pages git switch --orphan gh-pages git commit -a -m "initial commit of gh-pages" --allow-empty git push -u origin gh-pages # go back to branch git checkout $main_branch
Verify that Github Pages is enabled by going to your repository > Settings > Pages. It should report “Your site is live”, on the branch “gh-pages”.
Generate Chart .tgz files
We will have the chart-releaser utility generate the .tgz files for each Chart version first. This is because the .tgz and its calculated hash are required in the next step when generating index.yaml entries.
# token used for Github API authentication, per prerequisites CR_TOKEN=<githubPAT> # generate Chart tgz files git checkout $main_branch helm package charts/* -d .cr-release-packages # verify 'nginx-0.1.0.tgz' exists ls -l .cr-release-packages/ # upload .tgz via API as Github Release cr upload -r $repo_name -o $owner_name --skip-existing -t $CR_TOKEN
This can be validated from the Github web UI, in the ‘Releases’ section of your repository.
Generate index.yaml
Now that we have the .tgz generated, we can use these files to populate the entries for index.yaml.
# switch to branch that Github Pages serves git checkout gh-pages # generate entries for Chart releases cr index -i ./index.yaml -r $repo_name -o $owner_name # show entries generated cat index.yaml # commit and push, making it publicly visible git add index.yaml git commit -m "updated index.yaml" index.yaml git push # wait a few seconds, then validate content can be retrieved sleep 30 curl https://$owner_name.github.io/$repo_name/index.yaml
Validate from Helm client
With our index.yaml and Chart .tgz files fully published, it is a fully-functioning public Helm Repository.
# current repo list helm repo list # add our new Github repo helm repo add $repo_name https://$owner_name.github.io/$repo_name helm repo list # show chart versions available (only 0.1.0) helm search repo -l $repo_name # show general chart information chart_name=nginx full_chart_name=$repo_name/$chart_name helm show chart $full_chart_name # values for release release_name=mynginx1 release_ns=default # dry run of Chart, does not touch cluster version=0.1.0 helm install --dry-run $release_name $full_chart_name --version $version -n $release_ns
Note that we only did a dry-run of the chart release in the interest of simplicity. Nothing was installed into the Kubernetes cluster.
Versioning the Chart
Helm Charts are continually enhanced, so let’s go through the day-2 task of versioning this Helm Chart.
# make sure we are on charts branch git checkout $main_branch # increment to new version (0.1.0 was original) new_version=0.2.0 sed -i "s/^version: .*/version: $new_version/" charts/nginx/Chart.yaml # generate new .tgz for new version helm package charts/* -d .cr-release-packages # validate new .tgz exists ls -l .cr-release-packages/ # upload new .tgz as Github Release cr upload -r $repo_name -o $owner_name --skip-existing -t $CR_TOKEN # generate additional index entry for new version git checkout gh-pages cr index -i ./index.yaml -r $repo_name -o $owner_name git commit -m "updated index.yaml for $new_version" index.yaml git push # back to chart branch git checkout $main_branch
Validate new Chart version using Helm client
You could validate the new nginx-0.2.0.tgz file is found in the ‘Releases’ section of the Github web UI, and index.yaml has been updated with entries for both version ‘0.1.0’ and ‘0.2.0’. But instead let’s use the Helm client to validate.
# show chart versions available (still only 0.1.0) helm search repo -l $repo_name # do repo update helm repo update $repo_name # check available versions again (now both 0.1.0 and 0.2.0) helm search repo -l $repo_name # dry run of new Chart version version=0.2.0 helm install --dry-run $release_name $full_chart_name --version $version -n $release_ns
REFERENCES
Markus Lippert, Host Helm charts via GitHub with Chart Releaser
Jamie Magee, how to host your Helm chart repository on GitHub
Anup Dubey, How to host Helm Chart repository on Github
github chart-releaser-action for Github Actions
colinwilson.uk, signing helm charts with chart-releaser-action
Piotr Minkowski, shows Circle CI raw ‘cr’ commands for generating helm chart
Github, Github Pages enablement