ChartMuseum

Codefresh build status Go Report Card GoDoc


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.