Skip to content

Helm Chart Repository Guide

Artifact Keeper provides a Helm chart repository for hosting and distributing Kubernetes application packages.

Endpoint

Helm operations use the /helm endpoint:

http://localhost:8080/helm

Configuration

Add Helm Repository

Add Artifact Keeper as a Helm chart repository:

Terminal window
helm repo add artifact-keeper http://localhost:8080/helm

With authentication:

Terminal window
helm repo add artifact-keeper http://localhost:8080/helm \
--username your-username \
--password your-password

Update Repository Index

Fetch the latest chart information:

Terminal window
helm repo update

List Repositories

View configured repositories:

Terminal window
helm repo list

Publishing Charts

Create a Helm Chart

Generate a new chart:

Terminal window
helm create my-chart

This creates a chart structure:

my-chart/
├── Chart.yaml
├── values.yaml
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── _helpers.tpl
└── charts/

Chart.yaml

Define chart metadata in Chart.yaml:

apiVersion: v2
name: my-chart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.0.0"
keywords:
- application
- kubernetes
maintainers:
- name: Your Name
email: you@example.com
home: https://github.com/yourusername/my-chart
sources:
- https://github.com/yourusername/my-chart
dependencies:
- name: postgresql
version: "12.1.0"
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled

Package Chart

Create a chart archive:

Terminal window
helm package my-chart

This creates my-chart-0.1.0.tgz.

Publish Chart

Push the chart to Artifact Keeper using the Helm OCI or HTTP protocol:

Option 1: Using helm-push Plugin

Install the helm-push plugin:

Terminal window
helm plugin install https://github.com/chartmuseum/helm-push

Push the chart:

Terminal window
helm cm-push my-chart-0.1.0.tgz artifact-keeper

Or push directly from directory:

Terminal window
helm cm-push my-chart/ artifact-keeper

Option 2: Using curl

Terminal window
curl -u username:password \
--data-binary "@my-chart-0.1.0.tgz" \
http://localhost:8080/helm/api/charts

Option 3: OCI Registry (if supported)

Terminal window
# Login to OCI registry
helm registry login localhost:8080 -u username
# Package and push
helm push my-chart-0.1.0.tgz oci://localhost:8080/helm

Installing Charts

Search for Charts

Search the repository:

Terminal window
helm search repo artifact-keeper
helm search repo artifact-keeper/my-chart

Show chart details:

Terminal window
helm show chart artifact-keeper/my-chart
helm show values artifact-keeper/my-chart
helm show all artifact-keeper/my-chart

Install Chart

Install a chart from Artifact Keeper:

Terminal window
helm install my-release artifact-keeper/my-chart

Install specific version:

Terminal window
helm install my-release artifact-keeper/my-chart --version 0.1.0

Install with custom values:

Terminal window
helm install my-release artifact-keeper/my-chart \
--set service.type=LoadBalancer \
--set replicaCount=3

Or use a values file:

Terminal window
helm install my-release artifact-keeper/my-chart -f custom-values.yaml

Install to Specific Namespace

Terminal window
helm install my-release artifact-keeper/my-chart \
--namespace my-namespace \
--create-namespace

Managing Releases

List Installed Charts

Terminal window
helm list
helm list --namespace my-namespace
helm list --all-namespaces

Upgrade Release

Terminal window
helm upgrade my-release artifact-keeper/my-chart

Upgrade to specific version:

Terminal window
helm upgrade my-release artifact-keeper/my-chart --version 0.2.0

Rollback Release

Terminal window
helm rollback my-release
helm rollback my-release 1 # Rollback to specific revision

Uninstall Release

Terminal window
helm uninstall my-release
helm uninstall my-release --namespace my-namespace

Chart Versioning

Semantic Versioning

Follow semantic versioning in Chart.yaml:

version: 1.2.3
# Major.Minor.Patch

Version Constraints

In chart dependencies:

dependencies:
- name: redis
version: "~6.2.0" # >= 6.2.0, < 6.3.0
repository: http://localhost:8080/helm
- name: postgresql
version: "^12.0.0" # >= 12.0.0, < 13.0.0
repository: http://localhost:8080/helm

App Version

Track application version separately:

version: 1.0.0 # Chart version
appVersion: "2.5.1" # Application version

Chart Dependencies

Define Dependencies

In Chart.yaml:

dependencies:
- name: redis
version: "17.0.0"
repository: http://localhost:8080/helm
condition: redis.enabled
- name: postgresql
version: "12.1.0"
repository: http://localhost:8080/helm
condition: postgresql.enabled
tags:
- database

Download Dependencies

Terminal window
helm dependency update my-chart

This downloads dependencies to charts/ directory.

List Dependencies

Terminal window
helm dependency list my-chart

Chart Repository Index

The repository index is automatically maintained at /helm/index.yaml.

View Index

Terminal window
curl http://localhost:8080/helm/index.yaml

Example index.yaml:

apiVersion: v1
entries:
my-chart:
- name: my-chart
version: 0.1.0
description: A Helm chart for Kubernetes
created: "2024-01-15T10:00:00Z"
digest: sha256:abc123...
urls:
- http://localhost:8080/helm/charts/my-chart-0.1.0.tgz
- name: my-chart
version: 0.2.0
description: A Helm chart for Kubernetes
created: "2024-01-20T10:00:00Z"
digest: sha256:def456...
urls:
- http://localhost:8080/helm/charts/my-chart-0.2.0.tgz

Integration with CI/CD

GitHub Actions

name: Package and Publish Helm Chart
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Helm
uses: azure/setup-helm@v3
with:
version: '3.13.0'
- name: Package chart
run: |
helm package charts/my-chart --version ${{ github.ref_name }}
- name: Install helm-push plugin
run: |
helm plugin install https://github.com/chartmuseum/helm-push
- name: Add Helm repository
run: |
helm repo add artifact-keeper http://registry.example.com/helm \
--username ${{ secrets.HELM_USER }} \
--password ${{ secrets.HELM_PASSWORD }}
- name: Push chart
run: |
helm cm-push my-chart-*.tgz artifact-keeper

GitLab CI

publish-chart:
image: alpine/helm:latest
stage: deploy
script:
- helm plugin install https://github.com/chartmuseum/helm-push
- helm repo add artifact-keeper $HELM_REPO_URL --username $HELM_USER --password $HELM_PASSWORD
- helm package charts/my-chart
- helm cm-push my-chart-*.tgz artifact-keeper
only:
- tags

Jenkins Pipeline

pipeline {
agent any
tools {
helm 'Helm 3.13'
}
stages {
stage('Package and Publish') {
steps {
sh '''
helm plugin install https://github.com/chartmuseum/helm-push
helm repo add artifact-keeper ${HELM_REPO_URL} \
--username ${HELM_USER} \
--password ${HELM_PASSWORD}
helm package charts/my-chart
helm cm-push my-chart-*.tgz artifact-keeper
'''
}
}
}
}

Testing Charts

Lint Chart

Validate chart syntax and structure:

Terminal window
helm lint my-chart

Template Rendering

Preview rendered Kubernetes manifests:

Terminal window
helm template my-release my-chart

With custom values:

Terminal window
helm template my-release my-chart -f custom-values.yaml

Dry Run Installation

Test installation without deploying:

Terminal window
helm install my-release artifact-keeper/my-chart --dry-run --debug

Chart Testing

Use chart-testing tool:

Terminal window
# Install ct
brew install chart-testing
# Lint and test
ct lint --charts charts/my-chart
ct install --charts charts/my-chart

Advanced Features

Provenance and Integrity

Sign charts with GPG:

Terminal window
# Package and sign
helm package my-chart --sign --key 'Your Name' --keyring ~/.gnupg/secring.gpg
# Verify signature
helm verify my-chart-0.1.0.tgz

Chart Hooks

Define lifecycle hooks in templates:

apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-setup"
annotations:
"helm.sh/hook": pre-install
"helm.sh/hook-weight": "0"
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
spec:
containers:
- name: setup
image: busybox
command: ["sh", "-c", "echo Setting up..."]
restartPolicy: Never

Chart Library

Create reusable chart libraries:

Chart.yaml
apiVersion: v2
name: common
type: library
version: 1.0.0

Use in other charts:

dependencies:
- name: common
version: "1.0.0"
repository: http://localhost:8080/helm

Troubleshooting

Repository Not Found

Update repository index:

Terminal window
helm repo update

Verify repository URL:

Terminal window
helm repo list

Authentication Errors

Re-add repository with credentials:

Terminal window
helm repo remove artifact-keeper
helm repo add artifact-keeper http://localhost:8080/helm \
--username your-username \
--password your-password

Chart Installation Failures

Enable debug output:

Terminal window
helm install my-release artifact-keeper/my-chart --debug

Check Kubernetes events:

Terminal window
kubectl get events --namespace my-namespace

Version Conflicts

List available versions:

Terminal window
helm search repo artifact-keeper/my-chart --versions

Install specific version:

Terminal window
helm install my-release artifact-keeper/my-chart --version 0.1.0

Best Practices

Chart Structure

my-chart/
├── Chart.yaml # Chart metadata
├── values.yaml # Default values
├── values.schema.json # JSON schema for validation
├── README.md # Chart documentation
├── templates/
│ ├── NOTES.txt # Post-install notes
│ ├── _helpers.tpl # Template helpers
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── tests/
│ └── test-connection.yaml
└── .helmignore # Ignore patterns

Values.yaml

Provide sensible defaults:

replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
tag: "1.21"
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: ""
annotations: {}
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi

Documentation

Include NOTES.txt for post-install instructions:

Thank you for installing {{ .Chart.Name }}.
Your release is named {{ .Release.Name }}.
To learn more about the release, try:
$ helm status {{ .Release.Name }}
$ helm get all {{ .Release.Name }}
To access the application:
{{- if .Values.ingress.enabled }}
http://{{ index .Values.ingress.hosts 0 "host" }}
{{- else }}
kubectl port-forward service/{{ include "my-chart.fullname" . }} 8080:{{ .Values.service.port }}
{{- end }}

See Also