{"id":13486691,"url":"https://github.com/helm/chartmuseum","last_synced_at":"2025-12-15T14:59:41.108Z","repository":{"id":37665031,"uuid":"104032019","full_name":"helm/chartmuseum","owner":"helm","description":"helm chart repository server","archived":false,"fork":false,"pushed_at":"2025-04-07T06:43:52.000Z","size":23237,"stargazers_count":3669,"open_issues_count":125,"forks_count":402,"subscribers_count":56,"default_branch":"main","last_synced_at":"2025-04-09T22:09:19.757Z","etag":null,"topics":["chartmuseum","charts","helm","kubernetes"],"latest_commit_sha":null,"homepage":"https://chartmuseum.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/helm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"code-of-conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2017-09-19T05:48:21.000Z","updated_at":"2025-04-09T16:18:32.000Z","dependencies_parsed_at":"2023-02-12T21:01:44.542Z","dependency_job_id":"cd17e68f-7c00-48c5-ba96-ec267fe93479","html_url":"https://github.com/helm/chartmuseum","commit_stats":{"total_commits":514,"total_committers":89,"mean_commits":5.775280898876405,"dds":0.5758754863813229,"last_synced_commit":"a02769a5d23ba49afb247ba1b0ca8ca7efa6c335"},"previous_names":["chartmuseum/chartmuseum","kubernetes-helm/chartmuseum"],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/helm%2Fchartmuseum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/helm%2Fchartmuseum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/helm%2Fchartmuseum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/helm%2Fchartmuseum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/helm","download_url":"https://codeload.github.com/helm/chartmuseum/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248119294,"owners_count":21050755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chartmuseum","charts","helm","kubernetes"],"created_at":"2024-07-31T18:00:49.950Z","updated_at":"2025-12-15T14:59:41.099Z","avatar_url":"https://github.com/helm.png","language":"Go","funding_links":[],"categories":["Go","kubernetes"],"sub_categories":[],"readme":"# ChartMuseum\n\n[![GitHub Actions status](https://github.com/helm/chartmuseum/workflows/build/badge.svg)](https://github.com/helm/chartmuseum/actions?query=workflow%3Abuild)\n[![Go Report Card](https://goreportcard.com/badge/github.com/helm/chartmuseum)](https://goreportcard.com/report/github.com/helm/chartmuseum)\n[![GoDoc](https://godoc.org/github.com/helm/chartmuseum?status.svg)](https://godoc.org/github.com/helm/chartmuseum)\n\n\u003cp align=\"center\"\u003e\u003cimg align=\"center\" src=\"logo2.png\"\u003e\u003c/p\u003e\u003cbr/\u003e\n\n*ChartMuseum* is an open-source **[Helm Chart Repository](https://helm.sh/docs/topics/chart_repository/)** server written in Go (Golang), with support for cloud storage backends, including [Google Cloud Storage](https://cloud.google.com/storage/), [Amazon S3](https://aws.amazon.com/s3/), [Microsoft Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/blobs/), [Alibaba Cloud OSS Storage](https://www.alibabacloud.com/product/oss), [Openstack Object Storage](https://developer.openstack.org/api-ref/object-store/), [Oracle Cloud Infrastructure Object Storage](https://cloud.oracle.com/storage), [Baidu Cloud BOS Storage](https://cloud.baidu.com/product/bos.html), [Tencent Cloud Object Storage](https://intl.cloud.tencent.com/product/cos), [DigitalOcean Spaces](https://www.digitalocean.com/products/spaces/), [Minio](https://min.io/), and [etcd](https://etcd.io/).\n\nWorks as a valid Helm Chart Repository, and also provides an API for uploading charts.\n\n\u003cimg width=\"120\" align=\"right\" src=\"https://github.com/redblue9771/gopher-vector/raw/master/gopher-side_color.png\"\u003e\n\u003cimg width=\"40\" align=\"right\" src=\"https://github.com/redblue9771/gopher-vector/raw/master/gopher-side_color.png\"\u003e\n\nPowered by some great Go technology:\n- [helm/helm](https://github.com/helm/helm) - for working with charts\n- [gin-gonic/gin](https://github.com/gin-gonic/gin) - for HTTP routing\n- [urfave/cli](https://github.com/urfave/cli) - for command line option parsing\n- [spf13/viper](https://github.com/spf13/viper) - for configuration\n- [uber-go/zap](https://github.com/uber-go/zap) - for logging\n- [chartmuseum/auth](https://github.com/chartmuseum/auth) - for auth\n- [chartmuseum/storage](https://github.com/chartmuseum/storage) - for multi-cloud storage\n\n## API\n\n### Helm Chart Repository\n- `GET /index.yaml` - retrieved when you run `helm repo add chartmuseum http://localhost:8080/`\n- `GET /charts/mychart-0.1.0.tgz` - retrieved when you run `helm install chartmuseum/mychart`\n- `GET /charts/mychart-0.1.0.tgz.prov` - retrieved when you run `helm install` with the `--verify` flag\n\n### Chart Manipulation\n- `POST /api/charts` - upload a new chart version\n- `POST /api/prov` - upload a new provenance file\n- `DELETE /api/charts/\u003cname\u003e/\u003cversion\u003e` - delete a chart version (and corresponding provenance file)\n- `GET /api/charts` - list all charts\n- `GET /api/charts/\u003cname\u003e` - list all versions of a chart\n- `GET /api/charts/\u003cname\u003e/\u003cversion\u003e` - describe a chart version\n- `GET /api/charts/\u003cname\u003e/\u003cversion\u003e/templates` - get chart template\n- `GET /api/charts/\u003cname\u003e/\u003cversion\u003e/values` - get chart values\n- `HEAD /api/charts/\u003cname\u003e` - check if chart exists (any versions)\n- `HEAD /api/charts/\u003cname\u003e/\u003cversion\u003e` - check if chart version exists\n\n### Server Info\n- `GET /` - HTML welcome page\n- `GET /info` - returns current ChartMuseum version\n- `GET /health` - returns 200 OK\n\n## Uploading a Chart Package\n\u003csub\u003e*Follow **\"How to Run\"** section below to get ChartMuseum up and running at ht\u003cspan\u003etp:/\u003c/span\u003e/localhost:8080*\u003csub\u003e\n\nFirst create `mychart-0.1.0.tgz` using the [Helm CLI](https://docs.helm.sh/using_helm/#installing-helm):\n```\ncd mychart/\nhelm package .\n```\n\nUpload `mychart-0.1.0.tgz`:\n```bash\ncurl --data-binary \"@mychart-0.1.0.tgz\" http://localhost:8080/api/charts\n```\n\nIf you've signed your package and generated a [provenance file](https://github.com/helm/helm-www/blob/master/content/en/docs/topics/provenance.md), upload it with:\n```bash\ncurl --data-binary \"@mychart-0.1.0.tgz.prov\" http://localhost:8080/api/prov\n```\n\nBoth files can also be uploaded at once (or one at a time) on the `/api/charts` route using the `multipart/form-data` format:\n\n```bash\ncurl -F \"chart=@mychart-0.1.0.tgz\" -F \"prov=@mychart-0.1.0.tgz.prov\" http://localhost:8080/api/charts\n```\n\nYou can also use the [helm-push plugin](https://github.com/chartmuseum/helm-push):\n```\nhelm cm-push mychart/ chartmuseum\n```\n\n## Installing Charts into Kubernetes\nAdd the URL to your *ChartMuseum* installation to the local repository list:\n```bash\nhelm repo add chartmuseum http://localhost:8080\n```\n\nSearch for charts:\n```bash\nhelm search repo chartmuseum/\n```\n\nInstall chart:\n```bash\nhelm install chartmuseum/mychart --generate-name\n```\n\n## How to Run\n### CLI\n#### Installation\n\nYou can use the installer script:\n```\ncurl https://raw.githubusercontent.com/helm/chartmuseum/main/scripts/get-chartmuseum | bash\n```\n\nor download manually from the [releases page](https://github.com/helm/chartmuseum/releases),\nwhich also contains all package checksums and signatures.\n\nDetermine your version with `chartmuseum --version`.\n\n#### Configuration\nShow all CLI options with `chartmuseum --help`. Common configurations can be seen below.\n\nAll command-line options can be specified as environment variables, which are defined by the command-line option, capitalized, with all `-`'s replaced with `_`'s.\n\nFor example, the env var `STORAGE_AMAZON_BUCKET` can be used in place of `--storage-amazon-bucket`.\n\n##### Using a configuration file\nUse `chartmuseum --config config.yaml` to read configuration from a file.\n\nWhen using file-based configuration, the corresponding option name can be looked up in [`pkg/config/vars.go`]( https://github.com/helm/chartmuseum/blob/main/pkg/config/vars.go). It would be the key of `configVars` entry corresponding to the command line option / environment variable. For example, `--storage` corresponds to `storage.backend` in the configuration file.\n\nHere's a complete example of a `config.yaml`:\n\n```yaml\ndebug: true\nport: 8080\nstorage.backend: local\nstorage.local.rootdir: \u003cstorage_path\u003e\nbearerauth: 1\nauthrealm: \u003cauthorization server url\u003e\nauthservice: \u003cauthorization server service name\u003e\nauthcertpath: \u003cpath to authorization server public pem file\u003e\nauthactionssearchpath: \u003coptional: JMESPath to find allowed actions in a jwt token\u003e\ndepth: 2\n```\n\n#### Using with Amazon S3 or Compatible services like Minio or DigitalOcean.\nMake sure your environment is properly setup to access `my-s3-bucket`\n\nFor Amazon S3, `endpoint` is automatically inferred.\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"amazon\" \\\n  --storage-amazon-bucket=\"my-s3-bucket\" \\\n  --storage-amazon-prefix=\"\" \\\n  --storage-amazon-region=\"us-east-1\"\n```\n\nFor S3 compatible services like Minio, set the credentials using environment variables and pass the `endpoint`.\n\n```bash\nexport AWS_ACCESS_KEY_ID=\"\"\nexport AWS_SECRET_ACCESS_KEY=\"\"\nchartmuseum --debug --port=8080 \\\n  --storage=\"amazon\" \\\n  --storage-amazon-bucket=\"my-s3-bucket\" \\\n  --storage-amazon-prefix=\"\" \\\n  --storage-amazon-region=\"us-east-1\" \\\n  --storage-amazon-endpoint=\"my-s3-compatible-service-endpoint\"\n```\n\nYou need at least the following permissions inside your IAM Policy\n```yaml\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"AllowListObjects\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:ListBucket\"\n      ],\n      \"Resource\": \"arn:aws:s3:::my-s3-bucket\"\n    },\n    {\n      \"Sid\": \"AllowObjectsCRUD\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:DeleteObject\",\n        \"s3:GetObject\",\n        \"s3:PutObject\"\n      ],\n      \"Resource\": \"arn:aws:s3:::my-s3-bucket/*\"\n    }\n  ]\n}\n```\n\nIn order to work with AWS service accounts you may need to set `AWS_SDK_LOAD_CONFIG=1` in your environment.\nFor more context, please see [here](https://github.com/helm/chartmuseum/issues/280#issuecomment-592292527).\n\nIf you are using S3-Compatible storage, provider of S3 storage has [disabled path-style and force virtual hosted-style](https://aws.amazon.com/cn/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/), you can use specify `storage-amazon-force-path-style` options as following example:\n```\nexport AWS_ACCESS_KEY_ID=\"\"\nexport AWS_SECRET_ACCESS_KEY=\"\"\nchartmuseum --debug --port=8080 \\\n  --storage=\"amazon\" \\\n  --storage-amazon-bucket=\"my-s3-bucket\" \\\n  --storage-amazon-prefix=\"\" \\\n  --storage-amazon-region=\"us-east-1\" \\\n  --storage-amazon-endpoint=\"my-s3-compatible-service-endpoint\"\n  --storage-amazon-force-path-style=false\n```\n\n\nFor DigitalOcean, set the credentials using environment variable and pass the `endpoint`.\nNote below, that the region `us-east-1` needs to be set, since that is how the DigitalOcean cli implementation functions. The actual region of your spaces location is defined by the endpoint. Below we are using Frankfurt as an example.\n```bash\nexport AWS_ACCESS_KEY_ID=\"spaces_access_key\"\nexport AWS_SECRET_ACCESS_KEY=\"spaces_secret_key\"\n  chartmuseum --debug --port=8080 \\\n  --storage=\"amazon\" \\\n  --storage-amazon-bucket=\"my_spaces_name\" \\\n  --storage-amazon-prefix=\"my_spaces_name_subfolder\" \\\n  --storage-amazon-region=\"us-east-1\" \\\n  --storage-amazon-endpoint=\"https://fra1.digitaloceanspaces.com\"\n```\nThe access_key and secret_key can be generated from the DigitalOcean console, under the section API/Spaces_access_keys.\n\nNote: on certain S3-based storage backends, the `LastModified` field on objects\nis truncated to the nearest second. For more info, please see issue [#152](https://github.com/helm/chartmuseum/issues/152).\n\nIn order to mitigate this, you may use use the `--storage-timestamp-tolerance` option.\nFor example, to round to the nearest second, you could use `--storage-timestamp-tolerance=1s`.\nFor acceptable values to use for this field, please see [here](https://golang.org/pkg/time/#ParseDuration).\n\n#### Using with Google Cloud Storage\nMake sure your environment is properly setup to access `my-gcs-bucket`.\n\nOne way to do so is to set the `GOOGLE_APPLICATION_CREDENTIALS` var in your environment, pointing to the JSON file containing your service account key:\n```\nexport GOOGLE_APPLICATION_CREDENTIALS=\"/home/user/Downloads/[FILE_NAME].json\"\n```\n\nMore info on Google Cloud authentication can be found [here](https://cloud.google.com/docs/authentication/getting-started).\n\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"google\" \\\n  --storage-google-bucket=\"my-gcs-bucket\" \\\n  --storage-google-prefix=\"\"\n```\n\n#### Using with Microsoft Azure Blob Storage\n\nMake sure your environment is properly setup to access `mycontainer`.\n\nTo do so, you must set the following env vars:\n- `AZURE_STORAGE_ACCOUNT`\n- `AZURE_STORAGE_ACCESS_KEY`\n\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"microsoft\" \\\n  --storage-microsoft-container=\"mycontainer\" \\\n  --storage-microsoft-prefix=\"\"\n```\n\n#### Using with Alibaba Cloud OSS Storage\n\nMake sure your environment is properly setup to access `my-oss-bucket`.\n\nTo do so, you must set the following env vars:\n- `ALIBABA_CLOUD_ACCESS_KEY_ID`\n- `ALIBABA_CLOUD_ACCESS_KEY_SECRET`\n\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"alibaba\" \\\n  --storage-alibaba-bucket=\"my-oss-bucket\" \\\n  --storage-alibaba-prefix=\"\" \\\n  --storage-alibaba-endpoint=\"oss-cn-beijing.aliyuncs.com\"\n```\n\n#### Using with Openstack Object Storage\n\nMake sure your environment is properly setup to access `mycontainer`.\n\nTo do so, you must set the following env vars (depending on your openstack version):\n- `OS_AUTH_URL`\n- either `OS_PROJECT_NAME` or `OS_TENANT_NAME` or `OS_PROJECT_ID` or `OS_TENANT_ID`\n- either `OS_DOMAIN_NAME` or `OS_DOMAIN_ID`\n- either `OS_USERNAME` or `OS_USERID`\n- `OS_PASSWORD`\n\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"openstack\" \\\n  --storage-openstack-container=\"mycontainer\" \\\n  --storage-openstack-prefix=\"\" \\\n  --storage-openstack-region=\"myregion\"\n```\n\nFor Swift V1 Auth you must set the following env vars:\n- `ST_AUTH`\n- `ST_USER`\n- `ST_KEY`\n\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"openstack\" \\\n  --storage-openstack-auth=\"v1\" \\\n  --storage-openstack-container=\"mycontainer\" \\\n  --storage-openstack-prefix=\"\"\n```\n\n\n#### Using with Oracle Cloud Infrastructure Object Storage\n\nMake sure your environment is properly setup to access `my-ocs-bucket`.\n\nMore info on Oracle Cloud Infrastructure authentication can be found [here](https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm).\n\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"oracle\" \\\n  --storage-oracle-bucket=\"my-ocs-bucket\" \\\n  --storage-oracle-prefix=\"\" \\\n  --storage-oracle-compartmentid=\"ocid1.compartment.oc1..1234\"\n```\n\n#### Using with Baidu Cloud BOS Storage\n\nMake sure your environment is properly setup to access `my-bos-bucket`.\n\nTo do so, you must set the following env vars:\n- `BAIDU_CLOUD_ACCESS_KEY_ID`\n- `BAIDU_CLOUD_ACCESS_KEY_SECRET`\n\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"baidu\" \\\n  --storage-baidu-bucket=\"my-bos-bucket\" \\\n  --storage-baidu-prefix=\"\" \\\n  --storage-baidu-endpoint=\"bj.bcebos.com\"\n```\n\n#### Using with Tencent Cloud COS Storage\n\nMake sure your environment is properly setup to access `my-cos-bucket`.\n\nTo do so, you must set the following env vars:\n- `TENCENT_CLOUD_COS_SECRET_ID`\n- `TENCENT_CLOUD_COS_SECRET_KEY`\n\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"tencent\" \\\n  --storage-tencent-bucket=\"my-cos-bucket\" \\\n  --storage-tencent-prefix=\"\" \\\n  --storage-tencent-endpoint=\"cos.ap-beijing.myqcloud.com\"\n```\n\n#### Using with etcd\n\nTo use etcd as backend you need the CA certificate and the signed key pair.\nSee [here](https://coreos.com/etcd/docs/latest/op-guide/security.html)\n\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"etcd\" \\\n  --storage-etcd-cafile=\"/path/to/ca.crt\" \\\n  --storage-etcd-certfile=\"/path/to/server.crt\" \\\n  --storage-etcd-keyfile=\"/path/to/server.key\" \\\n  --storage-etcd-prefix=\"\" \\\n  --storage-etcd-endpoint=\"http://localhost:2379\"\n```\n\n#### Using with local filesystem storage\nMake sure you have read-write access to `./chartstorage` (will create if doesn't exist on first upload)\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"local\" \\\n  --storage-local-rootdir=\"./chartstorage\"\n```\n\n#### Basic Auth\nIf both of the following options are provided, basic http authentication will protect all routes:\n- `--basic-auth-user=\u003cuser\u003e` - username for basic http authentication\n- `--basic-auth-pass=\u003cpass\u003e` - password for basic http authentication\n\nYou 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\n\n- `--auth-anonymous-get` - allow anonymous GET operations\n\n#### Bearer/Token Auth\n\nIf all of the following options are provided, bearer auth will protect all routes:\n- `--bearer-auth` - enables bearer auth\n- `--auth-realm=\u003crealm\u003e` - authorization server url\n- `--auth-service=\u003cservice\u003e` - authorization server service name\n- `--auth-cert-path=\u003cpath\u003e` - path to authorization server public pem file\n- `--auth-actions-search-path=\u003cJMESPath\u003e` - (optional) JMESPath to find allowed actions in a jwt token\n\nUsing options above, *ChartMuseum* is configured with a public key, and will accept RS256 JWT tokens signed by the associated private key, passed in the `Authorization` header. You can use the [chartmuseum/auth](https://github.com/chartmuseum/auth) Go library to generate valid JWT tokens.\n\n##### JWT Token without a custom JMESPath to find actions\n\nIn order to gain access to a specific resource, the JWT token must contain an `access` section in the claims. This section indicates which resources the user is able to access. Here is an example token payload:\n\n```json\n{\n  \"exp\": 1543995770,\n  \"iat\": 1543995470,\n  \"access\": [\n    {\n      \"type\": \"artifact-repository\",\n      \"name\": \"org1/repo1\",\n      \"actions\": [\n        \"pull\"\n      ]\n    }\n  ]\n}\n```\n\nThe `type` is always \"artifact-repository\", the `name` is the namespace/tenant (just use the string \"repo\" if using single-tenant server), and `actions` is an array of actions the user can perform (\"pull\" and/or \"push).\n\nIf your JWT token structure is different, you can configure a [JMESPath string](https://jmespath.org/). So you can define the way to find the allowed actions yourself.\nFor the `type` and the the `name` you can use following placeholder\n* name: `$NAMESPACE`\n* type: `$ACCESS_ENTRY_TYPE`\n\nE.g.: If you want to represent the default configuration, the JMESPath looks like: `access[?name=='$NAMESPACE' \u0026\u0026 type=='$ACCESS_ENTRY_TYPE'].actions[]`.\n\nFor more information about how this works, please see [chartmuseum/auth-server-example](https://github.com/chartmuseum/auth-server-example).\n\n\n#### HTTPS\nIf both of the following options are provided, the server will listen and serve HTTPS:\n- `--tls-cert=\u003ccrt\u003e` - path to tls certificate chain file\n- `--tls-key=\u003ckey\u003e` - path to tls key file\n\n##### HTTPS with Client Certificate Authentication\nIf 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:\n-  `--tls-ca-cert=\u003ccacert\u003e` - path to tls certificate file\n\n#### Just generating index.yaml\nYou can specify the `--gen-index` option if you only wish to use _ChartMuseum_ to generate your index.yaml file. Note that this will only work with `--depth=0`.\n\nThe 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.\n\n#### Other CLI options\n- `--log-json` - output structured logs as json\n- `--log-health` - log incoming /health requests\n- `--log-latency-integer` - log latency as an integer (nanoseconds) instead of a string\n- `--disable-api` - disable all routes prefixed with /api\n- `--disable-delete` - explicitly disable the delete chart route\n- `--disable-statefiles` - disable use of index-cache.yaml\n- `--allow-overwrite` - allow chart versions to be re-uploaded without ?force querystring\n- `--disable-force-overwrite` - do not allow chart versions to be re-uploaded, even with ?force querystring\n- `--chart-url=\u003curl\u003e` - absolute url for .tgzs in index.yaml\n- `--storage-amazon-endpoint=\u003cendpoint\u003e` - alternative s3 endpoint\n- `--storage-amazon-sse=\u003calgorithm\u003e` - s3 server side encryption algorithm\n- `--storage-openstack-cacert=\u003cpath\u003e` - path to a custom ca certificates bundle for openstack\n- `--chart-post-form-field-name=\u003cfield\u003e` - form field which will be queried for the chart file content\n- `--prov-post-form-field-name=\u003cfield\u003e` - form field which will be queried for the provenance file content\n- `--index-limit=\u003cnumber\u003e` - limit the number of parallel indexers\n- `--context-path=\u003cpath\u003e` - base context path (new root for application routes)\n- `--depth=\u003cnumber\u003e` - levels of nested repos for multitenancy\n- `--cors-alloworigin=\u003cvalue\u003e` - value to set in the Access-Control-Allow-Origin HTTP header\n- `--read-timeout=\u003cnumber\u003e` - socket read timeout for http server\n- `--write-timeout=\u003cnumber\u003e` - socker write timeout for http server\n\n### Docker Image\nAvailable via [GitHub Container Registry (GHCR)](https://github.com/orgs/helm/packages/container/package/chartmuseum).\n\nExample usage (local storage):\n```bash\ndocker run --rm -it \\\n  -p 8080:8080 \\\n  -e DEBUG=1 \\\n  -e STORAGE=local \\\n  -e STORAGE_LOCAL_ROOTDIR=/charts \\\n  -v $(pwd)/charts:/charts \\\n  ghcr.io/helm/chartmuseum:v0.16.3\n```\n\nExample usage (S3):\n```bash\ndocker run --rm -it \\\n  -p 8080:8080 \\\n  -e DEBUG=1 \\\n  -e STORAGE=\"amazon\" \\\n  -e STORAGE_AMAZON_BUCKET=\"my-s3-bucket\" \\\n  -e STORAGE_AMAZON_PREFIX=\"\" \\\n  -e STORAGE_AMAZON_REGION=\"us-east-1\" \\\n  -v ~/.aws:/home/chartmuseum/.aws:ro \\\n  ghcr.io/helm/chartmuseum:v0.16.3\n```\n\n### Helm Chart\nThere is a [Helm chart for *ChartMuseum*](https://github.com/chartmuseum/charts/tree/main/src/chartmuseum) itself.\n\nYou can also view it on [Artifact Hub](https://artifacthub.io/packages/helm/chartmuseum/chartmuseum).\n\nTo install:\n```bash\nhelm repo add chartmuseum https://chartmuseum.github.io/charts\nhelm install chartmuseum/chartmuseum\n```\n\nIf interested in making changes, please submit a PR to [chartmuseum/charts](https://github.com/chartmuseum/charts). Before doing any work, please check for any [currently open pull requests](https://github.com/chartmuseum/charts/pulls?q=is%3Apr+is%3Aopen). Thanks!\n\n## Multitenancy\nMultitenancy is supported with the `--depth` flag.\n\nTo begin, start with a directory structure such as\n```\ncharts\n├── org1\n│   ├── repoa\n│   │   └── nginx-ingress-0.9.3.tgz\n├── org2\n│   ├── repob\n│   │   └── chartmuseum-0.4.0.tgz\n```\n\nThis represents a storage layout appropriate for `--depth=2`. The organization level can be eliminated by using `--depth=1`. The default depth is 0 (singletenant server).\n\nStart the server with `--depth=2`, pointing to the `charts/` directory:\n```\nchartmuseum --debug --depth=2 --storage=\"local\" --storage-local-rootdir=./charts\n```\n\nThis example will provide two separate Helm Chart Repositories at the following locations:\n- `http://localhost:8080/org1/repoa`\n- `http://localhost:8080/org2/repob`\n\nThis should work with all supported storage backends.\n\nTo use the chart manipulation routes, simply place the name of the repo directly after \"/api\" in the route:\n\n```bash\ncurl -F \"chart=@mychart-0.1.0.tgz\" http://localhost:8080/api/org1/repoa/charts\n```\n\nYou may also experiment with the `--depth-dynamic` flag, which should allow for dynamic depth levels (i.e. all of `/api/charts`, `/api/myrepo/charts`, `/api/org1/repoa/charts`).\n\n## Pagination\n\nFor large chart repositories, you may wish to paginate the results from the `GET /api/charts` route.\n\nTo do so, add the `offset` and `limit` query params to the request. For example, to retrieve a list of 5 charts total, skipping the first 5 charts, you could use the following:\n\n```\nGET /api/charts?offset=5\u0026limit=5\n```\n\n## Cache\n\nBy default, the contents of `index.yaml` (per-tenant) will be stored in memory. This means that memory usage will continue to grow indefinitely as more charts are added to storage.\n\nYou may wish to offload this to an external cache store, especially for large, multitenant installations.\n\n### Cache Interval\n\nWhen dealing with thousands of charts, you may experience latency with the default settings. This is because upon each request, the storage backend is scanned for changes compared to the cache.\n\nIf you are ok with `index.yaml` being out-of-date for a fixed period of time, you can improve performance by using the `--cache-interval=\u003cinterval\u003e` option.\nWhen this setting is enabled, the charts available for each tenant are refreshed on a timer.\n\nFor example, to only check storage every 5 minutes, you can use `--cache-interval=5m`.\n\nFor valid values to use for this setting, please see [here](https://godoc.org/time#ParseDuration).\n\n### Using Redis\n\nExample of using Redis as an external cache store:\n```bash\nchartmuseum --debug --port=8080 \\\n  --storage=\"local\" \\\n  --storage-local-rootdir=\"./chartstorage\" \\\n  --cache=\"redis\" \\\n  --cache-redis-addr=\"localhost:6379\" \\\n  --cache-redis-password=\"\" \\\n  --cache-redis-db=0\n```\n\n\n## Prometheus Metrics\n\nChartMuseum exposes its [Prometheus metrics](https://prometheus.io/docs/concepts/metric_types/) at the `/metrics` route on the main port. This can be enabled with the `--enable-metrics` command-line flag or the `ENABLE_METRICS` environment variable.\n\n\u003e Note that the Kubernetes chart currently disables metrics by default (`ENABLE_METRICS=false` is set in the chart). The `--disable-metrics` command-line flag has be deprecated and will only be available in `v0.14.0` and prior.\n\nBelow are the current application metrics exposed. Note that there is a per tenant (repo) label. The repo label corresponds to the depth parameter, so a depth=2 as the example above would\nhave repo labels named `org1/repoa` and `org2/repob`.\n\n| Metric                                   | Type  | Labels     | Description                              |\n| ---------------------------------------- | ----- | ---------- | ---------------------------------------- |\n| chartmuseum_charts_served_total          | Gauge | {repo=\"*\"} | Total number of charts                   |\n| chartmuseum_chart_versions_served_total | Gauge | {repo=\"*\"} | Total number of chart versions available |\n\n*: see above for repo label\n\nThere are other general global metrics harvested (per process, hence for all tenants). You can get the complete list by using the `/metrics` route.\n\n| Metric                                     | Type    | Labels                                                | Description                               |\n| ------------------------------------------ | ------- | ----------------------------------------------------- | ----------------------------------------- |\n| chartmuseum_request_duration_seconds       | Summary | {quantile=\"0.5\"}, {quantile=\"0.9\"}, {quantile=\"0.99\"} | The HTTP request latencies in seconds     |\n| chartmuseum_request_duration_seconds_sum   |         |                                                       |                                           |\n| chartmuseum_request_duration_seconds_count |         |                                                       |                                           |\n| chartmuseum_request_size_bytes             | Summary | {quantile=\"0.5\"}, {quantile=\"0.9\"}, {quantile=\"0.99\"} | The HTTP request sizes in bytes           |\n| chartmuseum_request_size_bytes_sum         |         |                                                       |                                           |\n| chartmuseum_request_size_bytes_count       |         |                                                       |                                           |\n| chartmuseum_response_size_bytes            | Summary | {quantile=\"0.5\"}, {quantile=\"0.9\"}, {quantile=\"0.99\"} | The HTTP response sizes in bytes          |\n| chartmuseum_response_size_bytes_sum        |         |                                                       |                                           |\n| chartmuseum_response_size_bytes_count      |         |                                                       |                                           |\n| go_goroutines                              | Gauge   |                                                       | Number of goroutines that currently exist |\n\n\n## Notes on index.yaml\nThe 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.\n\n`GET /index.yaml` occurs when you run `helm repo add chartmuseum http://localhost:8080` or `helm repo update`.\n\nIf you manually add/remove a .tgz package from storage, it will be immediately reflected in `GET /index.yaml`.\n\nYou are no longer required to maintain your own version of index.yaml using `helm repo index --merge`.\n\nThe `--gen-index` CLI option (described above) can be used to generate and print index.yaml to stdout.\n\nUpon index regeneration, *ChartMuseum* will, however, save a statefile in storage called `index-cache.yaml` used for cache optimization. This file is only meant for internal use, but may be able to be used for migration to simple storage.\n\n## Mirroring the official Kubernetes repositories\nPlease see `scripts/mirror-k8s-repos.sh` for an example of how to download all .tgz packages from the official Kubernetes repositories (both stable and incubator).\n\nYou can then use *ChartMuseum* to serve up an internal mirror:\n```\nscripts/mirror-k8s-repos.sh\nchartmuseum --debug --port=8080 --storage=\"local\" --storage-local-rootdir=\"./mirror\"\n ```\n\n## Custom Welcome Page\n\nWith the flag `--web-template-path=\u003cpath\u003e`, you can specify the path to your custom welcome page.\n\nThe structure of the folder should be like this:\n\n```bash\nweb/\n  index.html\n  xyz.html\n  static/\n      main.css\n      main.js\n```\n\n\u003e ChartMuseum is using gin-gonic to serve the static files, this means that you can use go-template to render the files.\n\nIf you don't specify a custom welcome page, ChartMuseum will serve the default one.\n\n#### Artifact Hub\n\nBy setting the flag `--artifact-hub-repo-id \u003crepo id\u003e`, ChartMuseum will serve a `artifacthub-repo.yml` file with the\nspecified repo ID in the `repositoryID` field of the yaml file.\n\n```yaml\nrepositoryID: The ID of the Artifact Hub repository where the packages will be published to (optional, but it enables verified publisher)\n```\n\n##### Multitenancy\n\nFor multitenancy setups, you can provide a key value pair to the flag in the format: `--artifact-hub-repo-id \u003crepo\u003e=\u003crepo id\u003e`\n\n```bash\nchartmuseum --storage local --storage-local-rootdir /tmp/ --depth 1 --artifact-hub-repo-id org1=\u003crepo id\u003e --artifact-hub-repo-id org2=\u003crepo2 id\u003e\n```\n\nThe `artifacthub-repo.yml` file will then be served at `/org1/artifacthub-repo.yml` and `/org2/artifacthub-repo.yml`\n\n## Original Logo\n\n\u003csub\u003e**_\"Preserve your precious artifacts... in the cloud!\"_**\u003csub\u003e\n\n![](./logo.png)\n\n## Subprojects\n\nThe following subprojects are maintained by *ChartMuseum*:\n\n- [chartmuseum/helm-push](https://github.com/chartmuseum/helm-push) - Helm plugin to push chart package to ChartMuseum\n- [chartmuseum/storage](https://github.com/chartmuseum/storage) - Go library providing common interface for working across multiple cloud storage backends\n- [chartmuseum/auth](https://github.com/chartmuseum/auth) - Go library for generating ChartMuseum JWT Tokens, authorizing HTTP requests, etc.\n- [chartmuseum/auth-server-example](https://github.com/chartmuseum/auth-server-example) - Example server providing JWT tokens for ChartMuseum auth\n- [chartmuseum/testbed](https://github.com/chartmuseum/testbed) - Docker testbed for continuous integration\n- [chartmuseum/www](https://github.com/chartmuseum/www) - chartmuseum.com static site source code\n- [chartmuseum/ui](https://github.com/chartmuseum/ui) - ChartMuseum frontend UI\n\n## Community\nYou can reach the *ChartMuseum* community and developers in the [Kubernetes Slack](https://slack.k8s.io) **#chartmuseum** channel.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhelm%2Fchartmuseum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhelm%2Fchartmuseum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhelm%2Fchartmuseum/lists"}