Lesson 18 Chart Packaging & Registries
Theme:
Lesson 18 · Slide 1

Chart Packaging & Registries

From local charts to distributed registries: packaging, publishing, and signing Helm charts.

Lesson 18 · Slide 2

helm package & SemVer Versioning

# Package a chart into a .tgz archive
helm package ./mychart/
# Output: mychart-1.2.0.tgz

# Package with explicit version override
helm package ./mychart/ --version 2.0.0-rc1

# Package into a specific directory
helm package ./mychart/ -d ./dist/
# Chart.yaml — two version fields
apiVersion: v2
name: mychart
version: 1.2.0        # Chart version (SemVer) — bump on every chart change
appVersion: "3.8.1"    # App version — the software being deployed
Note: version tracks the chart itself (templates, values, helpers). appVersion tracks the application (e.g., nginx 1.25.3). They change independently.
Lesson 18 · Slide 3

Chart Repositories & index.yaml

# Add a chart repository
helm repo add bitnami https://charts.bitnami.com/bitnami

# Update local repo cache
helm repo update

# Search for charts
helm search repo bitnami/nginx

# Remove a repository
helm repo remove bitnami
# index.yaml — repository metadata
apiVersion: v1
entries:
  mychart:
    - name: mychart
      version: 1.2.0
      appVersion: "3.8.1"
      created: "2026-04-01T10:00:00Z"
      digest: sha256:abc123...
      urls:
        - https://charts.example.com/mychart-1.2.0.tgz
# Generate / update index.yaml
helm repo index ./dist/ --url https://charts.example.com
Lesson 18 · Slide 4

Self-Hosted Repos: ChartMuseum & Harbor

ChartMuseum

# Run ChartMuseum locally
docker run -d -p 8080:8080 \
  -e STORAGE=local \
  -e STORAGE_LOCAL_ROOTDIR=/charts \
  -v $(pwd)/charts:/charts \
  chartmuseum/chartmuseum

# Push a chart
curl --data-binary "@mychart-1.2.0.tgz" \
  http://localhost:8080/api/charts

# Add as repo
helm repo add local \
  http://localhost:8080

Harbor

# Harbor supports both classic
# chart repos and OCI registries

# Classic: add Harbor as a repo
helm repo add harbor \
  https://harbor.example.com/chartrepo/myproject \
  --username admin --password secret

# OCI: push directly
helm push mychart-1.2.0.tgz \
  oci://harbor.example.com/myproject
Note: ChartMuseum is chart-only. Harbor is a full container + chart registry with RBAC, vulnerability scanning, and replication.
Lesson 18 · Slide 5

OCI Registries & GitHub Container Registry

# Login to an OCI registry
helm registry login ghcr.io -u USERNAME

# Push a packaged chart to OCI
helm push mychart-1.2.0.tgz oci://ghcr.io/myorg/charts

# Pull a chart from OCI
helm pull oci://ghcr.io/myorg/charts/mychart --version 1.2.0

# Install directly from OCI
helm install myrelease oci://ghcr.io/myorg/charts/mychart --version 1.2.0

GitHub Pages as a Chart Repo

# 1. Package charts into docs/ or gh-pages branch
helm package ./mychart/ -d ./docs/

# 2. Generate index
helm repo index ./docs/ --url https://myorg.github.io/helm-charts

# 3. Push to gh-pages branch, then:
helm repo add myorg https://myorg.github.io/helm-charts

OCI registries (oci://) are the modern standard. They reuse existing container registry infrastructure — no separate index.yaml needed.

Lesson 18 · Slide 6

Signing & Verifying Charts

# Package and sign with a GPG key
helm package ./mychart/ --sign \
  --key "Helm Signing Key" \
  --keyring ~/.gnupg/secring.gpg
# Produces: mychart-1.2.0.tgz + mychart-1.2.0.tgz.prov

# Verify a chart before installing
helm verify mychart-1.2.0.tgz --keyring ~/.gnupg/pubring.gpg

# Install with verification
helm install myrelease mychart-1.2.0.tgz --verify \
  --keyring ~/.gnupg/pubring.gpg
# .prov file (provenance) contents:
# - Chart metadata hash
# - Chart.yaml contents
# - PGP signature block

Provenance files ensure chart integrity and authenticity. In regulated environments, always sign charts in CI and verify on install.

Lesson 18 · Slide 7

CI/CD Pipeline & .helmignore

# Typical CI/CD stages for Helm charts
# 1. Lint
helm lint ./mychart/ --strict

# 2. Template & validate
helm template ./mychart/ | kubeval --strict

# 3. Package
helm package ./mychart/ --version ${CI_TAG}

# 4. Push to registry
helm push mychart-${CI_TAG}.tgz oci://ghcr.io/myorg/charts
# .helmignore — files excluded from helm package
.git
.gitignore
.helmignore
*.md
tests/
ci/
.env
secrets.yaml
*.swp
*.bak

.helmignore works like .gitignore. Keep packages lean by excluding docs, tests, CI configs, and sensitive files.

Lesson 18 · Slide 8

Summary

Next: Lesson 19 →

1 / ?