Registries

Helm 3 supports OCI for package distribution. Chart packages are able to be stored and shared across OCI-based registries.

Enabling OCI Support

Prior to Helm v3.8.0, OCI support was considered experimental and needed to be enabled. As of v3.8.0 it is enabled by default.

To enable OCI experimental support for Helm versions prior to v3.8.0, please set HELM_EXPERIMENTAL_OCI in the environment:

  1. export HELM_EXPERIMENTAL_OCI=1

Running a registry

Starting a registry for test purposes is trivial. As long as you have Docker installed, run the following command:

  1. docker run -dp 5000:5000 --restart=always --name registry registry

This will start a registry server at localhost:5000.

Use docker logs -f registry to see the logs and docker rm -f registry to stop.

If you wish to persist storage, you can add -v $(pwd)/registry:/var/lib/registry to the command above.

For more configuration options, please see the docs.

Note: on macOS, port 5000 may be occupied by “AirPlay Receiver”. You can either choose a different local port (e.g. -p 5001:5000), or disable this under System Preferences > Sharing.

Auth

If you wish to enable auth on the registry, you can do the following-

First, create file auth.htpasswd with username and password combo:

  1. htpasswd -cB -b auth.htpasswd myuser mypass

Then, start the server, mounting that file and setting the REGISTRY_AUTH env var:

  1. docker run -dp 5000:5000 --restart=always --name registry \
  2. -v $(pwd)/auth.htpasswd:/etc/docker/registry/auth.htpasswd \
  3. -e REGISTRY_AUTH="{htpasswd: {realm: localhost, path: /etc/docker/registry/auth.htpasswd}}" \
  4. registry

Commands for working with registries

The registry subcommand

login

login to a registry (with manual password entry)

  1. $ helm registry login -u myuser localhost:5000
  2. Password:
  3. Login succeeded

logout

logout from a registry

  1. $ helm registry logout localhost:5000
  2. Logout succeeded

The push subcommand

upload a chart to a registry

  1. $ helm push mychart-0.1.0.tgz oci://localhost:5000/helm-charts
  2. Pushed: localhost:5000/helm-charts/mychart:0.1.0
  3. Digest: sha256:ec5f08ee7be8b557cd1fc5ae1a0ac985e8538da7c93f51a51eff4b277509a723

Extra notes on the push subcommand

The push subcommand can only be used against .tgz files created ahead of time using helm package.

When using helm push to upload a chart an OCI registry, the reference must be prefixed with oci:// and must not contain the basename or tag.

The registry reference basename is inferred from from the chart’s name, and the tag is inferred from the chart’s semantic version. This is currently a strict requirement ( more info here).

Certain registries require the repository and/or namespace (if specified) to be created beforehand. Otherwise, an error will be produced during the helm push operation.

If you have created a provenance file (.prov), and it is present next to the chart .tgz file, it will automatically be uploaded to the registry upon push. This results in an extra layer on the Helm chart manifest.

Users of the helm-push plugin (for uploading charts to ChartMuseum) may experience issues, since the plugin conflicts with the new, built-in push. As of version v0.10.0, the plugin has been renamed to cm-push.

Other subcommands

Support for the oci:// protocol is also available in various other subcommands. Here is a complete list:

  • helm pull
  • helm show
  • helm template
  • helm install
  • helm upgrade

The basename (chart name) of the registry reference is included for any type of action involving chart download (vs. helm push where it is omitted).

Here are a few examples of using the subcommands listed above against OCI-based charts:

  1. $ helm pull oci://localhost:5000/helm-charts/mychart --version 0.1.0
  2. Pulled: localhost:5000/helm-charts/mychart:0.1.0
  3. Digest: sha256:0be7ec9fb7b962b46d81e4bb74fdcdb7089d965d3baca9f85d64948b05b402ff
  4. $ helm show all oci://localhost:5000/helm-charts/mychart --version 0.1.0
  5. apiVersion: v2
  6. appVersion: 1.16.0
  7. description: A Helm chart for Kubernetes
  8. name: mychart
  9. ...
  10. $ helm template myrelease oci://localhost:5000/helm-charts/mychart --version 0.1.0
  11. ---
  12. # Source: mychart/templates/serviceaccount.yaml
  13. apiVersion: v1
  14. kind: ServiceAccount
  15. ...
  16. $ helm install myrelease oci://localhost:5000/helm-charts/mychart --version 0.1.0
  17. NAME: myrelease
  18. LAST DEPLOYED: Wed Oct 27 15:11:40 2021
  19. NAMESPACE: default
  20. STATUS: deployed
  21. REVISION: 1
  22. NOTES:
  23. ...
  24. $ helm upgrade myrelease oci://localhost:5000/helm-charts/mychart --version 0.2.0
  25. Release "myrelease" has been upgraded. Happy Helming!
  26. NAME: myrelease
  27. LAST DEPLOYED: Wed Oct 27 15:12:05 2021
  28. NAMESPACE: default
  29. STATUS: deployed
  30. REVISION: 2
  31. NOTES:
  32. ...

Specifying dependencies

Dependencies of a chart can be pulled from a registry using the dependency update subcommand.

The repository for a given entry in Chart.yaml is specified as the registry reference without the basename:

  1. dependencies:
  2. - name: mychart
  3. version: "2.7.0"
  4. repository: "oci://localhost:5000/myrepo"

This will fetch oci://localhost:5000/myrepo/mychart:2.7.0 when dependency update is executed.

Helm chart manifest

Example Helm chart manifest as represented in a registry (note the mediaType fields):

  1. {
  2. "schemaVersion": 2,
  3. "config": {
  4. "mediaType": "application/vnd.cncf.helm.config.v1+json",
  5. "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111",
  6. "size": 117
  7. },
  8. "layers": [
  9. {
  10. "mediaType": "application/vnd.cncf.helm.chart.content.v1.tar+gzip",
  11. "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617",
  12. "size": 2487
  13. }
  14. ]
  15. }

The following example contains a provenance file (note the extra layer):

  1. {
  2. "schemaVersion": 2,
  3. "config": {
  4. "mediaType": "application/vnd.cncf.helm.config.v1+json",
  5. "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111",
  6. "size": 117
  7. },
  8. "layers": [
  9. {
  10. "mediaType": "application/vnd.cncf.helm.chart.content.v1.tar+gzip",
  11. "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617",
  12. "size": 2487
  13. },
  14. {
  15. "mediaType": "application/vnd.cncf.helm.chart.provenance.v1.prov",
  16. "digest": "sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741a",
  17. "size": 643
  18. }
  19. ]
  20. }

Migrating from chart repos

Migrating from classic chart repositories (index.yaml-based repos) is as simple using helm pull, then using helm push to upload the resulting .tgz files to a registry.

Deprecated features and strict naming policies

Prior to Helm 3.7.0, Helm’s OCI support was slightly different. As a result of HIP 6, in an effort to simplify and stabilize this feature set, several changes have been implemented:

  • The helm chart subcommand has been removed
  • The chart cache has been removed (no helm chart list etc.)
  • OCI registry references are now always prefixed with oci://
  • The basename of the registry reference must always match the chart’s name
  • The tag of the registry reference must always match the chart’s semantic version (i.e. no latest tags)
  • The chart layer media type was switched from application/tar+gzip to application/vnd.cncf.helm.chart.content.v1.tar+gzip

Thank you for your patience as the Helm team continues to work on stabilizing native support for OCI registries.