Getting Started With ChartMuseum

When you build custom Helm charts for your organisation, you need somewhere to store and distribute them. Public registries like Artifact Hub are not suitable for internal charts. ChartMuseum is an open-source Helm chart repository server that you can run on your own infrastructure — with support for local storage, AWS S3, GCS, Azure Blob, and more.


How It Fits Into Your Workflow

flowchart LR
    Dev[Developer] -->|helm package| Chart[chart.tgz]
    Chart -->|curl POST| CM[ChartMuseum Server]
    CM -->|stores in| Storage[Local / S3 / GCS / Azure]
    CI[CI Pipeline] -->|helm install| CM
    Cluster[Kubernetes Cluster] -->|pulls chart| CI

ChartMuseum exposes a standard Helm repository API — any Helm client can add it as a repository and install charts from it exactly like any public repo.


Why ChartMuseum

  • Self-hosted — your charts never leave your infrastructure
  • Cloud storage backends — S3, GCS, Azure Blob, Oracle Cloud, Baidu Cloud
  • REST API — push, delete, and manage charts programmatically
  • Helm native — works with standard helm repo add and helm install
  • Multi-tenant — supports chart repositories per team via URL paths
  • Authentication — basic auth and bearer token support built in

Alternatives worth knowing: For organisations already running a container registry, OCI-compatible registries (ECR, GCR, Docker Hub) now support Helm charts natively. Harbor is a full-featured registry that includes a Helm chart repository. ChartMuseum remains the lightest, dedicated-purpose option.


Installation

docker run --rm -it \
  -p 8080:8080 \
  -e DEBUG=1 \
  -e STORAGE=local \
  -e STORAGE_LOCAL_ROOTDIR=/charts \
  -v $(pwd)/charts:/charts \
  ghcr.io/helm/chartmuseum:v0.16.3

Binary

curl -LO https://s3.amazonaws.com/chartmuseum/release/latest/bin/linux/amd64/chartmuseum
chmod +x ./chartmuseum
mv ./chartmuseum /usr/local/bin
chartmuseum --version

Helm (deploy into Kubernetes)

helm repo add chartmuseum https://chartmuseum.github.io/charts
helm repo update
helm install chartmuseum chartmuseum/chartmuseum \
  --set env.open.STORAGE=local

Running with Local Storage

chartmuseum \
  --debug \
  --port=8080 \
  --storage="local" \
  --storage-local-rootdir="./chartstorage"

ChartMuseum starts and serves the repository at http://localhost:8080.


Running with AWS S3

chartmuseum \
  --port=8080 \
  --storage="amazon" \
  --storage-amazon-bucket="my-helm-charts" \
  --storage-amazon-region="us-east-1"

Make sure the instance or container has an IAM role with s3:GetObject, s3:PutObject, s3:ListBucket, and s3:DeleteObject on your bucket.


Adding ChartMuseum as a Helm Repository

helm repo add mychartmuseum http://localhost:8080
helm repo update
helm repo list

Once added, you can search and install from it like any other repo:

helm search repo mychartmuseum
helm install my-release mychartmuseum/my-chart

Uploading Charts

Package your chart first, then push it via the ChartMuseum API:

# Package the chart into a .tgz
helm lint ./my-chart
helm package ./my-chart

# Upload to ChartMuseum
curl --data-binary "@my-chart-0.1.0.tgz" http://localhost:8080/api/charts

# Refresh Helm's local cache
helm repo update

# Verify it appears
helm search repo mychartmuseum
helm search repo -l mychartmuseum   # -l shows all versions

Managing Chart Versions

Update version in Chart.yaml before packaging a new release:

# Chart.yaml
version: 0.2.0   # was 0.1.0
appVersion: "2.0"

Then package and push:

helm package ./my-chart               # produces my-chart-0.2.0.tgz
curl --data-binary "@my-chart-0.2.0.tgz" http://localhost:8080/api/charts
helm repo update
helm search repo -l mychartmuseum    # shows both 0.1.0 and 0.2.0

Install a specific version:

helm install my-release mychartmuseum/my-chart --version 0.1.0

Full Workflow Example

# 1. Clone demo chart repo
git clone https://github.com/devops-monk/helm-nginx-nodeport-chart.git
cd helm-nginx-nodeport-chart

# 2. Start ChartMuseum
chartmuseum --debug --port=8080 --storage=local --storage-local-rootdir=./chartstorage &

# 3. Add as Helm repo
helm repo add mychartmuseum http://localhost:8080

# 4. Lint, package, and push
helm lint devopsmonk-webapp
helm package devopsmonk-webapp/
curl --data-binary "@helm-webapp-0.1.0.tgz" http://localhost:8080/api/charts

# 5. Install from ChartMuseum
helm repo update
helm install demo-nginx mychartmuseum/helm-webapp

# 6. Verify
helm ls
kubectl get pods

Useful API Endpoints

ChartMuseum exposes a REST API beyond the standard Helm repository interface:

EndpointMethodDescription
/index.yamlGETStandard Helm repo index
/api/chartsGETList all charts (JSON)
/api/chartsPOSTUpload a chart
/api/charts/<name>/<version>DELETEDelete a specific chart version
/healthGETHealth check

Demo Repository

The chart used in this guide is available at: devops-monk/helm-nginx-nodeport-chart

Abhay

Abhay Pratap Singh

DevOps Engineer passionate about automation, cloud infrastructure, and self-hosted tools. I write about Kubernetes, Terraform, DNS, and everything in between.