Building a Production-Ready Helm Repository on Nexus: A Practical Guide

In modern Kubernetes-based platforms, Helm has become the de facto standard for packaging and distributing applications. However, using Helm effectively in a team or enterprise environment requires more than just writing charts — it requires a reliable, versioned, and centralized distribution mechanism.

This article walks through the full lifecycle of setting up a Helm repository on Nexus, from repository creation to chart packaging, publishing, validation, and installation. More importantly, it explains the reasoning behind each step, focusing on long-term maintainability, reproducibility, and operational safety.


1. Why Use Nexus for Helm Charts?

Before diving into the implementation, it’s important to understand the motivation.

A Helm repository is not just storage — it is:

  • A distribution layer for Kubernetes applications
  • A version control mechanism for deployments
  • A contract between DevOps and developers

Using Nexus as a Helm repository provides:

  • Centralized artifact management
  • Access control and authentication
  • Integration with CI/CD pipelines (e.g., Jenkins)
  • Immutable versioning when properly configured

https://github.com/faustobranco/devops-db/tree/master/knowledge-base/helm-repo


2. Creating the Helm Repository in Nexus

We start by creating a hosted Helm repository in Nexus:

Format: helm (hosted)
Deployment policy: Disable redeploy

Repository URL:

https://nexus.devops-db.internal/repository/helm-devops-db/

Why these settings matter

Helm (hosted)
This ensures Nexus understands Helm-specific metadata and index structure.

Disable redeploy
This is critical.

  • Prevents overwriting existing chart versions
  • Enforces immutability
  • Guarantees reproducibility of deployments

In practice, this means:

If version 1.0.6 exists, it can never be replaced — only incremented.

This avoids one of the most dangerous anti-patterns in DevOps:

“Same version, different content”


3. Chart Structure: The Foundation

A valid and tested Helm chart must follow a predictable structure:

devops-api/
├── Chart.yaml
├── README.md
├── charts/
├── templates/
│   ├── configmap.yaml
│   ├── deployment.yaml
│   ├── ingress-canary.yaml
│   ├── ingress.yaml
│   ├── secret.yaml
│   └── service.yaml
└── values.yaml

Why structure matters

Helm is opinionated. This structure enables:

  • Template rendering consistency
  • Reusability of subcharts (charts/)
  • Separation of configuration (values.yaml) from logic (templates/)

Most importantly:

A chart must be fully testable locally before publishing

Publishing broken charts to a shared repository introduces cascading failures across environments.


4. Versioning: The Most Misunderstood Concept

Inside Chart.yaml:

apiVersion: v2
name: devops-api
description: A Helm chart for devops-api
type: application
version: 1.0.6
appVersion: "1.0.0"

Key distinction

  • version → Helm chart version
  • appVersion → Application version (informational only)

Why this matters

The Helm ecosystem treats these independently.

Chart version (version)

  • Drives packaging and distribution
  • Used by Helm to resolve upgrades
  • Must follow semantic versioning

Application version (appVersion)

  • Purely informational
  • Does not affect deployment logic
  • Can be omitted without impact

A critical principle:

The Helm chart must remain deployable independently of application versioning.

For example:

  • You may change templates without changing the application
  • You may update defaults without rebuilding the container

5. Packaging the Chart

To prepare the chart for distribution:

helm package devops-api/.

Output:

devops-api-1.0.6.tgz

Why packaging exists

Helm packages are:

  • Immutable artifacts
  • Versioned units of deployment
  • Comparable to Docker images for Kubernetes manifests

This step ensures:

  • All templates are bundled
  • Version metadata is embedded
  • The artifact is portable

6. Uploading to Nexus

Upload the packaged chart:

curl -u usr_jenkins_nexus:1234qwer \
  --upload-file devops-api-1.0.6.tgz \
  https://nexus.devops-db.internal/repository/helm-devops-db/

Why use curl (and not Helm push plugins)

Using curl provides:

  • Simplicity
  • CI/CD compatibility
  • No dependency on Helm plugins

This makes pipelines more predictable and easier to debug.

Security note

Credentials should never be hardcoded in real scenarios. Use:

  • Environment variables
  • Secret managers
  • CI/CD credential stores

7. Registering the Repository in Helm

To consume the repository:

helm repo add devops-db https://nexus.devops-db.internal/repository/helm-devops-db/
helm repo update

Why this step is required

Helm maintains a local cache of repository indexes.

helm repo update:

  • Downloads index.yaml
  • Refreshes available chart versions

Without this step, newly uploaded charts will not be visible.


8. Verifying Published Charts

Search available charts:

helm search repo devops-db

NAME                     CHART VERSION  APP VERSION  DESCRIPTION
devops-db/devops-api     1.0.6         	            A Helm chart for devops-api
devops-db/iplocation-api 1.0.5          1.0.0        A Helm chart for iplocation api
devops-db/totp-api       1.0.7          1.0.0        A Helm chart for TOTP API Validator

Why verification matters

This step confirms:

  • Chart indexing is working
  • Version is correctly registered
  • Metadata is readable

Skipping this step can lead to confusing deployment errors later.


9. Installing or Upgrading the Chart

Finally, deploy the application:

helm upgrade --install devops-api . \
  --values values.yaml \
  -n devops-api \
  --create-namespace

Why use upgrade --install

This is a best practice.

It ensures:

  • Idempotency
  • Safe re-runs in CI/CD
  • No need to check if release exists

Why use values.yaml

Separating configuration allows:

  • Environment-specific customization
  • Reusability of the same chart
  • Clean separation between code and config

10. End-to-End Flow Summary

The complete workflow:

  1. Create Helm repo in Nexus (immutable policy)
  2. Develop and test chart locally
  3. Define version in Chart.yaml
  4. Package chart (helm package)
  5. Upload artifact (via curl)
  6. Update Helm repo index locally
  7. Validate availability (helm search)
  8. Deploy using helm upgrade --install

Leave a Reply

Your email address will not be published. Required fields are marked *