ChartMuseum is an open-source server written in Go (Golang), with support for cloud storage backends, including Google Cloud Storage, Amazon S3, Microsoft Azure Blob Storage, Alibaba Cloud OSS Storage, Openstack Object Storage, Oracle Cloud Infrastructure Object Storage, Baidu Cloud BOS Storage, Tencent Cloud Object Storage, Netease Cloud NOS Storage, DigitalOcean Spaces, Minio, and etcd.
Works as a valid Helm Chart Repository, and also provides an API for uploading charts.
Powered by some great Go technology:
API
Helm Chart Repository
GET /index.yamlhelm repo add chartmuseum http://localhost:8080/GET /charts/mychart-0.1.0.tgzhelm install chartmuseum/mychartGET /charts/mychart-0.1.0.tgz.provhelm install--verify
Chart Manipulation
POST /api/chartsPOST /api/provDELETE /api/charts//GET /api/chartsGET /api/charts/GET /api/charts//HEAD /api/charts/HEAD /api/charts//
Server Info
GET /GET /health
Uploading a Chart Package
Follow "How to Run" section below to get ChartMuseum up and running at http://localhost:8080
mychart-0.1.0.tgz
cd mychart/
helm package .
mychart-0.1.0.tgz
If you've signed your package and generated a provenance file, upload it with:
/api/chartsmultipart/form-data
You can also use the helm-push plugin:
helm push mychart/ chartmuseum
Installing Charts into Kubernetes
Add the URL to your ChartMuseum installation to the local repository list:
Search for charts:
Install chart:
How to Run
CLI
Installation
Install binary using GoFish:
gofish install chartmuseum
==> Installing chartmuseum...
🐠 chartmuseum 0.12.0: installed in 95.431145ms
or manually:
latest
latest$(curl -s https://s3.amazonaws.com/chartmuseum/release/stable.txt)v0.12.0
chartmuseum --version
Configuration
chartmuseum --help
-_
STORAGE_AMAZON_BUCKET--storage-amazon-bucket
Using config yaml file example
-.--storagestorage.backend
Using with Amazon S3 or Compatible services like Minio or DigitalOcean.
my-s3-bucket
endpoint
endpoint
You need at least the following permissions inside your IAM Policy
AWS_SDK_LOAD_CONFIG=1
endpointus-east-1
The access_key and secret_key can be generated from the DigitalOcean console, under the section API/Spaces_access_keys.
LastModified
--storage-timestamp-tolerance--storage-timestamp-tolerance=1s
Using with Google Cloud Storage
my-gcs-bucket
GOOGLE_APPLICATION_CREDENTIALS
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json"
More info on Google Cloud authentication can be found here.
Using with Microsoft Azure Blob Storage
mycontainer
To do so, you must set the following env vars:
AZURE_STORAGE_ACCOUNTAZURE_STORAGE_ACCESS_KEY
Using with Alibaba Cloud OSS Storage
my-oss-bucket
To do so, you must set the following env vars:
ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET
Using with Openstack Object Storage
mycontainer
To do so, you must set the following env vars (depending on your openstack version):
OS_AUTH_URLOS_PROJECT_NAMEOS_TENANT_NAMEOS_PROJECT_IDOS_TENANT_IDOS_DOMAIN_NAMEOS_DOMAIN_IDOS_USERNAMEOS_USERIDOS_PASSWORD
Using with Oracle Cloud Infrastructure Object Storage
my-ocs-bucket
More info on Oracle Cloud Infrastructure authentication can be found here.
Using with Baidu Cloud BOS Storage
my-bos-bucket
To do so, you must set the following env vars:
BAIDU_CLOUD_ACCESS_KEY_IDBAIDU_CLOUD_ACCESS_KEY_SECRET
Using with Tencent Cloud COS Storage
my-cos-bucket
To do so, you must set the following env vars:
TENCENT_CLOUD_COS_SECRET_IDTENCENT_CLOUD_COS_SECRET_KEY
Using with Netease Cloud NOS Storage
my-nos-bucket
To do so, you must set the following env vars:
NETEASE_CLOUD_ACCESS_KEY_IDNETEASE_CLOUD_ACCESS_KEY_SECRET
Using with etcd
To use etcd as backend you need the CA certificate and the signed key pair. See here
Using with local filesystem storage
./chartstorage
Basic Auth
If both of the following options are provided, basic http authentication will protect all routes:
--basic-auth-user=--basic-auth-pass=
You may want basic auth to only be applied to operations that can change Charts, i.e. PUT, POST and DELETE. So to avoid basic auth on GET operations use
--auth-anonymous-get
Bearer/Token Auth
If all of the following options are provided, bearer auth will protect all routes:
--bearer-auth--auth-realm=--auth-service=--auth-cert-path=
Authorization
access
typenameactions
For more information about how this works, please see chartmuseum/auth-server-example.
HTTPS
If both of the following options are provided, the server will listen and serve HTTPS:
--tls-cert=--tls-key=
HTTPS with Client Certificate Authentication
If the above HTTPS values are provided in addition to below, the server will listen and serve HTTPS and authenticate client requests against the CA certificate:
--tls-ca-cert=
Just generating index.yaml
--gen-index--depth=0
The contents of index.yaml will be printed to stdout and the program will exit. This is useful if you are satisfied with your current Helm CI/CD process and/or don't want to monitor another webservice.
Other CLI options
--log-json--log-health--log-latency-integer--disable-api--disable-delete--disable-statefiles--allow-overwrite--disable-force-overwrite--chart-url=--storage-amazon-endpoint=--storage-amazon-sse=--storage-openstack-cacert=--chart-post-form-field-name=--prov-post-form-field-name=--index-limit=--context-path=--depth=--cors-alloworigin=--read-timeout=--write-timeout=
Docker Image
Available via Docker Hub.
Example usage (local storage):
Example usage (S3):
Helm Chart
There is a Helm chart for ChartMuseum itself which can be found in the official Helm charts repository.
You can also view it on Helm Hub.
To install:
If interested in making changes, please submit a PR to helm/charts. Before doing any work, please check for any currently open pull requests. Thanks!
Multitenancy
--depth
To begin, start with a directory structure such as
charts
├── org1
│ ├── repoa
│ │ └── nginx-ingress-0.9.3.tgz
├── org2
│ ├── repob
│ │ └── chartmuseum-0.4.0.tgz
--depth=2--depth=1
--depth=2charts/
chartmuseum --debug --depth=2 --storage="local" --storage-local-rootdir=./charts
This example will provide two separate Helm Chart Repositories at the following locations:
http://localhost:8080/org1/repoahttp://localhost:8080/org2/repob
This should work with all supported storage backends.
To use the chart manipulation routes, simply place the name of the repo directly after "/api" in the route:
--depth-dynamic/api/charts/api/myrepo/charts/api/org1/repoa/charts
Pagination
GET /api/charts
offsetlimit
GET /api/charts?offset=5&limit=5
Cache
index.yaml
You may wish to offload this to an external cache store, especially for large, multitenant installations.
Using Redis
Example of using Redis as an external cache store:
Prometheus Metrics
/metrics--disable-metricsDISABLE_METRICS
DISABLE_METRICS=true
org1/repoaorg2/repob
Metric | Type | Labels | Description |
---|---|---|---|
chartmuseum_charts_served_total | Gauge | {repo="*"} | Total number of charts |
chartmuseum_charts_versions_served_total | Gauge | {repo="*"} | Total number of chart versions available |
*: see above for repo label
/metrics
Metric | Type | Labels | Description |
---|---|---|---|
chartmuseum_request_duration_seconds | Summary | {quantile="0.5"}, {quantile="0.9"}, {quantile="0.99"} | The HTTP request latencies in seconds |
chartmuseum_request_duration_seconds_sum | |||
chartmuseum_request_duration_seconds_count | |||
chartmuseum_request_size_bytes | Summary | {quantile="0.5"}, {quantile="0.9"}, {quantile="0.99"} | The HTTP request sizes in bytes |
chartmuseum_request_size_bytes_sum | |||
chartmuseum_request_size_bytes_count | |||
chartmuseum_response_size_bytes | Summary | {quantile="0.5"}, {quantile="0.9"}, {quantile="0.99"} | The HTTP response sizes in bytes |
chartmuseum_response_size_bytes_sum | |||
chartmuseum_response_size_bytes_count | |||
go_goroutines | Gauge | Number of goroutines that currently exist |
Notes on index.yaml
The repository index (index.yaml) is dynamically generated based on packages found in storage. If you store your own version of index.yaml, it will be completely ignored.
GET /index.yamlhelm repo add chartmuseum http://localhost:8080helm repo update
GET /index.yaml
helm repo index --merge
--gen-index
index-cache.yaml
Mirroring the official Kubernetes repositories
scripts/mirror_k8s_repos.sh
You can then use ChartMuseum to serve up an internal mirror:
scripts/mirror_k8s_repos.sh
chartmuseum --debug --port=8080 --storage="local" --storage-local-rootdir="./mirror"
Original Logo
"Preserve your precious artifacts... in the cloud!"
Subprojects
The following subprojects are maintained by ChartMuseum:
Community
You can reach the ChartMuseum community and developers in the Kubernetes Slack #chartmuseum channel.