Hosting a Helm repository on GitLab Pages

Simpler than on GitHub Pages

Posted by Tobias L. Maier on March 13, 2018

Helm is a Package Manager for Kubernetes. There are plenty of officially managed and hosted Helm Charts available, but still, there may be the a need to develop own Helm charts as well.

Helm charts are being versioned and hosted in a Chart Repository. The Helm documentation describes two options for hosting a Chart Repository. One is Google Cloud Storage (GCS), the other one GitHub Pages.

The official Kubernetes charts (kubernetes/charts) are hosted on GCS. It requires some 3rd party tooling to test and publish the charts to the GCS Chart repository. One piece of the puzzle is its repo-sync.sh script, but it is not an easily repeatable solution.

The GitHub Pages option describes only how to push a packaged chart manually to GitHub Pages. I googled for some blueprints and examples how to use for example Travis CI to do the packaging and deployment steps, but I did not find any workable solution.

This is why I consider to use GitLab, GitLab CI and GitLab Pages to host my public Chart repository. GitLab is an alternative to GitHub for Version Control, providing Continuous Integration/Continuous Delivery capabilities on top of it. GitLab offers also to host static websites for free. Similar to GitHub Pages, just more flexible, as not only Jekyll is supported as static website generator.

The idea is to use Helm as our static website generator and publish the generated repository to GitLab Pages.

The CI/CD pipeline consists of two jobs:

  1. Lint the Helm chart
  2. Generate and publish the Helm repository.

Create a .gitlab-ci.yml file with this jobs:

lint Helm Charts:
  image:
    name: linkyard/docker-helm
    entrypoint: ["/bin/sh", "-c"]
  stage: test
  script:
    - helm lint charts/*
    - helm lint charts/*/charts/*

pages:
  image:
    name: linkyard/docker-helm
    entrypoint: ["/bin/sh", "-c"]
  stage: deploy
  script:
    - helm init --client-only
    - mkdir -p ./public
    - "echo \"User-Agent: *\nDisallow: /\" > ./public/robots.txt"
    - helm package charts/* --destination ./public
    - helm repo index --url https://${CI_PROJECT_NAMESPACE}.gitlab.io/${CI_PROJECT_NAME} .
    - mv index.yaml ./public
  artifacts:
    paths:
      - public
  only:
    - master

Both jobs expect that the charts are located in a ./charts directory.

The first job lint Helm Charts is just a simple lint job. It checks if the charts are well formed and do not have any obvious syntax errors.

The second job pages packages the charts and creates an index.yaml file. The index.yaml file is the index of all published charts and its versions. GitLab takes all files of the public folder and publishes them at https://<group-name>.gitlab.io/<project-name>.

To use your new Chart repository, run $ helm repo add my-repo https://<group-name>.gitlab.io/<project-name> on your local computer.

If you are looking for a private Chart repo, consider ChartMuseum. There is also a Helm chart in development for it (see incubator/chartmuseum). It supports many backends (e.g. GCS or S3), but as far as I can see it supports HTTP Basic auth only.