Semantic Versioning and Helm charts are deeply intertwined, but their relationship isn’t as straightforward as you might think. The most surprising truth is that Helm’s chart version and the application version it deploys are independent concepts, and conflating them is a common source of confusion.
Let’s see this in action. Imagine we have a chart named my-app and we want to deploy version 1.2.0 of our application.
Here’s a simplified Chart.yaml for this scenario:
apiVersion: v2
name: my-app
description: A Helm chart for my awesome application
version: 0.1.0 # This is the chart version
appVersion: "1.2.0" # This is the application version
When you run helm install my-app ./my-app, Helm uses the version field (0.1.0 in this case) to track the chart release. The appVersion field ("1.2.0") is metadata that Helm doesn’t directly use for its own versioning but is crucial for understanding what application version is being deployed.
The problem this solves is managing the lifecycle of your application deployments through Kubernetes. Helm allows you to version your deployment configurations (the chart) separately from the actual application code it deploys. This is powerful because you might release multiple chart versions for the same application version (e.g., to fix chart bugs without changing the app) or deploy a new application version with an existing chart version (e.g., a quick patch).
Internally, Helm uses the version field for its release management. Every time you helm upgrade or helm install a chart, Helm increments its internal tracking for that release based on the chart’s version. The appVersion is primarily for human readability and for tools that consume Helm charts to understand which application version is associated with a given chart release.
Consider this scenario:
-
Initial Deploy:
Chart.yaml:version: 0.1.0,appVersion: "1.0.0"helm install my-release ./my-app- Helm release
my-releaseis now tracked as0.1.0. The deployed application is1.0.0.
-
Chart Bug Fix (No App Change):
- You fix a bug in the chart’s
templates/deployment.yaml. Chart.yaml:version: 0.1.1,appVersion: "1.0.0"(appVersion remains the same)helm upgrade my-release ./my-app- Helm release
my-releaseis now tracked as0.1.1. The deployed application is still1.0.0.
- You fix a bug in the chart’s
-
Application Update:
- You release a new version of your application,
1.1.0. Chart.yaml:version: 0.2.0,appVersion: "1.1.0"helm upgrade my-release ./my-app- Helm release
my-releaseis now tracked as0.2.0. The deployed application is now1.1.0.
- You release a new version of your application,
Notice how version and appVersion can move independently. The version field adheres to Semantic Versioning (e.g., MAJOR.MINOR.PATCH). This means 0.1.0 to 0.1.1 is a patch update to the chart, 0.1.1 to 0.2.0 is a minor update to the chart (potentially introducing new features or changes in how it deploys), and 0.2.0 to 1.0.0 would be a major breaking change for the chart itself.
The common pitfall is aligning version and appVersion too rigidly, often setting version: "1.2.0" when appVersion: "1.2.0". This ties your chart’s release cycle directly to your application’s release cycle, losing the flexibility to manage them independently. You should increment the chart version according to SemVer for the chart’s changes, and update appVersion to reflect the specific application version being deployed by that chart.
When you run helm list, you’ll see the chart version associated with each release. To see the appVersion for a deployed release, you can use helm get values <release-name>.
If you’re using a chart repository, the version field is what determines which chart version is fetched. For example, helm install my-release my-repo/my-app --version 0.1.1 will install chart version 0.1.1.
The appVersion is also a valuable field when you need to perform a rollback. helm rollback <release-name> <revision> rolls back the chart release to a previous revision, and the appVersion associated with that revision’s chart is what was deployed at that time.
The next logical step is to understand how to manage dependencies between different Helm charts, a feature that also leverages versioning.