Helm charts need proper artifact storage just like any other build output. If you’re deploying applications to Kubernetes, your charts are critical infrastructure. Storing them in a Git repository works for small teams, but as your Kubernetes footprint grows, you need a proper Helm chart repository that provides versioning, access control, and reliable distribution.
Many teams searching for “artifactory helm chart” are looking for exactly this: a reliable way to store, version, and distribute their Helm charts. This guide covers your options and shows you how to set up a private Helm repository that integrates with your CI/CD pipelines.
What Are Helm Charts?
Helm is the package manager for Kubernetes. A Helm chart is a collection of files that describe a set of Kubernetes resources - deployments, services, configmaps, secrets, and everything else your application needs to run.
A basic chart structure looks like this:
my-application/ Chart.yaml # Chart metadata (name, version, description) values.yaml # Default configuration values templates/ # Kubernetes manifest templates deployment.yaml service.yaml configmap.yaml charts/ # Dependencies (subcharts)Here’s a minimal Chart.yaml:
apiVersion: v2name: my-applicationdescription: A Helm chart for my web applicationtype: applicationversion: 1.2.0appVersion: '3.4.1'The key fields:
- version: The chart version (follows semver). This is what gets stored in your repository.
- appVersion: The version of the application being deployed (informational only).
Tip
Treat chart versions like any other artifact version. When you change your Kubernetes manifests, bump the chart version. This gives you a clear audit trail of what was deployed and when.
Why Helm Charts Need Proper Artifact Storage
You might wonder: if charts are just YAML files, why not keep them in Git alongside your application code?
That approach works initially, but it creates problems at scale:
1. Version Distribution
When multiple clusters or teams need to install your chart, they need a URL to pull from. Git repositories aren’t designed for this - you’d need everyone to clone the repo and reference local paths.
A Helm repository provides a stable URL:
helm install my-app https://charts.example.com/my-application --version 1.2.02. Dependency Management
Charts can depend on other charts. When you define dependencies in Chart.yaml, Helm needs to fetch them from somewhere:
dependencies: - name: postgresql version: '12.1.0' repository: 'https://charts.bitnami.com/bitnami' - name: internal-library version: '2.0.0' repository: 'https://your-org.mycloudrepo.io/helm/'Without a proper repository, sharing internal library charts between teams becomes manual and error-prone.
3. Access Control
Some charts contain sensitive configuration patterns or proprietary deployment logic. You need control over who can pull and push charts, with audit trails for compliance.
4. CI/CD Integration
Your deployment pipelines need a reliable source to pull charts from. Storing charts in a repository separate from your application code means:
- Build once, deploy many times
- Clear versioning of what’s deployed where
- Easy rollbacks to previous chart versions
Helm Chart Storage Options
You have several choices for hosting Helm charts, ranging from self-hosted to fully managed. Here’s an honest comparison.
ChartMuseum (Self-Hosted)
ChartMuseum is an open-source Helm chart repository server. It’s the simplest self-hosted option.
Pros:
- Free and open source
- Supports multiple storage backends (S3, GCS, Azure Blob, local filesystem)
- Simple to deploy as a container
- Basic authentication and multi-tenancy
Cons:
- You manage the infrastructure
- Limited enterprise features (no SSO, limited audit logging)
- Community support only
- No web UI for browsing charts
Best for: Small teams comfortable with self-hosting, local development environments.
Harbor
Harbor is an open-source container registry that also supports Helm charts via OCI artifacts.
Pros:
- Full-featured container registry plus Helm charts
- Vulnerability scanning for container images
- Rich access control and replication
- Active CNCF project with enterprise support options
Cons:
- Complex to deploy and operate
- Overkill if you only need Helm charts
- Significant infrastructure footprint
Best for: Organizations that need a unified container and Helm registry, especially air-gapped environments.
JFrog Artifactory
The market leader for artifact management. Supports virtually every artifact type, including Helm charts.
Pros:
- Universal repository (Helm, Docker, Maven, npm, everything)
- Enterprise features (SSO, fine-grained permissions, audit logs)
- Helm chart indexing and search
- Available as cloud or self-hosted
Cons:
- Expensive, especially at scale
- Consumption-based pricing means egress fees
- Complex licensing and feature tiers
- Steep learning curve for administration
Best for: Large enterprises already using Artifactory for other artifact types.
Info
Many teams search for “artifactory helm chart” because they’re evaluating Artifactory for this purpose. If cost is a concern, consider that Artifactory’s consumption-based pricing charges for every chart download. Active Kubernetes clusters can generate significant egress costs.
Cloud Provider Registries
AWS ECR, Google Artifact Registry, and Azure Container Registry all support Helm charts via OCI format.
AWS ECR:
# Push a chart to ECRhelm push my-chart-1.0.0.tgz oci://123456789.dkr.ecr.us-east-1.amazonaws.com/helm-charts
# Pull from ECRhelm pull oci://123456789.dkr.ecr.us-east-1.amazonaws.com/helm-charts/my-chart --version 1.0.0Pros:
- Native IAM integration for access control
- No additional infrastructure to manage
- Works well if you’re already on that cloud
Cons:
- Vendor lock-in
- Egress fees apply (especially significant for multi-cloud)
- IAM configuration can be complex
- Different authentication flow than traditional Helm repos
Best for: Teams fully committed to a single cloud provider.
CloudRepo
A cloud-native artifact repository that supports Helm charts alongside Maven, Gradle, and Python packages.
Pros:
- Predictable flat pricing (no egress fees)
- Simple setup and administration
- Support included on all plans
- Works with standard Helm commands
Cons:
- Fewer formats than Artifactory
- Cloud-only (no self-hosted option)
- Smaller feature set than enterprise platforms
Best for: Teams that want simple, predictable artifact management without enterprise complexity.
Setting Up a Private Helm Repository
Let’s walk through setting up a private Helm repository. We’ll use CloudRepo as the example, but the client-side commands work with any Helm repository.
Step 1: Create Your Repository
In CloudRepo, create a new Helm repository through the web interface or API. You’ll get a repository URL like:
https://your-org.mycloudrepo.io/helm/Step 2: Configure Helm to Use Your Repository
Add the repository to your local Helm configuration:
# Add the repository with authenticationhelm repo add myrepo https://your-org.mycloudrepo.io/helm/ \ --username your-username \ --password your-password
# Verify it's addedhelm repo list
# Update the repository indexhelm repo updateStep 3: Package Your Chart
Before uploading, package your chart into a .tgz archive:
# From the directory containing your charthelm package my-application/
# This creates: my-application-1.2.0.tgzStep 4: Push Your Chart
Upload the packaged chart to your repository. The exact command depends on your repository, but most support the helm push plugin or standard HTTP upload:
# Using the helm-push pluginhelm plugin install https://github.com/chartmuseum/helm-pushhelm cm-push my-application-1.2.0.tgz myrepo
# Or using curl for repositories that accept HTTP uploadscurl -u your-username:your-password \ -F "chart=@my-application-1.2.0.tgz" \ https://your-org.mycloudrepo.io/helm/api/chartsStep 5: Install from Your Repository
Now anyone with access can install your chart:
# Update to get the latest indexhelm repo update
# Search for available versionshelm search repo myrepo/my-application --versions
# Install a specific versionhelm install my-release myrepo/my-application --version 1.2.0
# Install with custom valueshelm install my-release myrepo/my-application \ --version 1.2.0 \ --values custom-values.yamlImportant
Always specify a version in production deployments. Using --version ensures you get exactly the chart you tested,
not whatever version happens to be latest when the deployment runs.
CI/CD Integration: Pushing Charts from Pipelines
Automating chart publishing is essential for consistent releases. Here are examples for common CI systems.
GitHub Actions
name: Release Helm Chart
on: push: tags: - 'chart-v*'
jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Install Helm uses: azure/setup-helm@v3 with: version: 'v3.14.0'
- name: Install helm-push plugin run: helm plugin install https://github.com/chartmuseum/helm-push
- name: Package chart run: | helm dependency update ./charts/my-application helm package ./charts/my-application
- name: Push to repository env: HELM_REPO_USERNAME: ${{ secrets.CLOUDREPO_USERNAME }} HELM_REPO_PASSWORD: ${{ secrets.CLOUDREPO_PASSWORD }} run: | helm repo add cloudrepo https://your-org.mycloudrepo.io/helm/ \ --username $HELM_REPO_USERNAME \ --password $HELM_REPO_PASSWORD helm cm-push my-application-*.tgz cloudrepoGitLab CI
stages: - package - publish
package-chart: stage: package image: alpine/helm:3.14.0 script: - helm dependency update ./charts/my-application - helm package ./charts/my-application artifacts: paths: - '*.tgz' expire_in: 1 hour
publish-chart: stage: publish image: alpine/helm:3.14.0 script: - helm plugin install https://github.com/chartmuseum/helm-push - helm repo add cloudrepo https://your-org.mycloudrepo.io/helm/ --username $CLOUDREPO_USERNAME --password $CLOUDREPO_PASSWORD - helm cm-push *.tgz cloudrepo only: - tagsJenkins Pipeline
pipeline { agent any
environment { HELM_REPO_URL = 'https://your-org.mycloudrepo.io/helm/' HELM_REPO_CREDS = credentials('cloudrepo-credentials') }
stages { stage('Package') { steps { sh ''' helm dependency update ./charts/my-application helm package ./charts/my-application ''' } }
stage('Publish') { when { tag pattern: "chart-v.*", comparator: "REGEXP" } steps { sh ''' helm plugin install https://github.com/chartmuseum/helm-push || true helm repo add cloudrepo $HELM_REPO_URL \ --username $HELM_REPO_CREDS_USR \ --password $HELM_REPO_CREDS_PSW helm cm-push *.tgz cloudrepo ''' } } }}Tip
For more CI/CD integration patterns, see our guide to GitHub Actions with CloudRepo, which covers artifact authentication and caching strategies that apply to Helm charts too.
Best Practices for Helm Chart Repositories
Version Every Change
Every chart modification should bump the version number. This isn’t optional - Helm repositories use the version field to track releases:
# Before: version 1.2.0# After adding a new environment variable to the deploymentversion: 1.2.1Use semantic versioning:
- MAJOR (2.0.0): Breaking changes to values.yaml or chart behavior
- MINOR (1.3.0): New features, backward compatible
- PATCH (1.2.1): Bug fixes, documentation updates
Separate Chart and App Versions
The version field is the chart version. The appVersion field tracks the underlying application:
version: 1.5.0 # Chart has had 5 minor updatesappVersion: '2.3.1' # Currently deploying app version 2.3.1This lets you update chart logic (add a health check, change resource defaults) independently of application releases.
Use Dependencies for Shared Logic
Extract common patterns into library charts that other charts can depend on:
dependencies: - name: common-deployment version: '1.0.0' repository: 'https://your-org.mycloudrepo.io/helm/'This reduces duplication across your organization’s charts.
Lint Before Publishing
Catch errors before they hit your repository:
# Validate chart structure and templateshelm lint ./charts/my-application
# Render templates to check outputhelm template my-release ./charts/my-application --debugDocument Your Values
A values.yaml file should be self-documenting:
# Number of replicas for the deployment# Minimum: 1 for dev, 3 for productionreplicaCount: 2
# Container image settingsimage: repository: your-registry/my-app tag: 'latest' # Override with specific version for production pullPolicy: IfNotPresent
# Resource limits and requests# Adjust based on your application's needsresources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 128MiImplement Access Control
Not everyone should push charts to production repositories. Set up permissions appropriately:
- Developers: Read access to pull charts
- CI/CD systems: Write access to push new versions
- Platform team: Admin access to manage repositories
Comparison: When to Use Which Option
| Requirement | Best Options |
|---|---|
| Minimal cost, small team | ChartMuseum (self-hosted) or GitHub Pages |
| Container + Helm in one | Harbor, cloud provider registries |
| Enterprise compliance | Artifactory, Harbor Enterprise |
| Simple, managed service | CloudRepo, cloud provider registries |
| Multi-cloud deployments | CloudRepo (no egress fees), ChartMuseum |
| Existing Artifactory users | Continue with Artifactory for consistency |
Cost Considerations
The hidden cost in Helm chart hosting is egress. Every time a cluster pulls a chart, that’s data transfer:
- ChartMuseum: You pay for the infrastructure (compute, storage, bandwidth)
- Artifactory: Consumption-based pricing includes egress fees
- Cloud registries: Egress fees apply, especially cross-region/cross-cloud
- CloudRepo: Flat pricing, no egress fees
For a team running 20 Kubernetes clusters that pull charts daily, egress can add up quickly with consumption-based pricing.
Common Issues and Solutions
Authentication Failures
If helm repo add fails with 401 errors:
# Make sure credentials are correctcurl -u username:password https://your-repo.example.com/helm/index.yaml
# Some repos need the full URL with trailing slashhelm repo add myrepo https://your-repo.example.com/helm/Chart Not Found After Push
The repository index might be cached:
# Force a repository index updatehelm repo update
# Check if the chart appears in the indexhelm search repo myrepo/my-application --versionsDependency Resolution Failures
If helm dependency update fails:
# Ensure all dependency repositories are addedhelm repo add bitnami https://charts.bitnami.com/bitnamihelm repo add internal https://your-org.mycloudrepo.io/helm/helm repo update
# Then update dependencieshelm dependency update ./charts/my-applicationNext Steps
You now understand why Helm charts need proper artifact storage, what your options are, and how to set up a private Helm repository with CI/CD integration.
For more on artifact management fundamentals, see our Artifact Management Guide. If you’re evaluating artifact repository options, our comparison of Artifactory alternatives covers the broader landscape.
Ready to store your Helm charts without worrying about egress fees? Try CloudRepo free for 14 days - no credit card required. Set up a Helm repository in minutes and see how simple artifact management can be.
Questions about Helm chart hosting or migrating from another repository? Contact our team - support is included with every CloudRepo plan.