If you want to manage Kubernetes more easily, you can use Helm. It helps you manage Kubernetes applications — Helm Charts helps you define, install, and upgrade even the most complex Kubernetes application. Charts are easy to create, version, share, and publish — so start using Helm and stop the copy-and-paste madness.

Let's create Your First Helm Chart!

Step 1. Generate Your First Chart

The best way to get started with a new chart is to use the helm create command to scaffold out an example we can build on. Use this command to create a new chart named my-angular-project in a new directory:

$ helm create my-angular-project

Helm will create a new directory in your project called my-angular-project with the structure shown below. Let's navigate our new chart (pun intended) to find out how it works.


The most important piece of the puzzle is the templates/ directory. This is where Helm finds the YAML definitions for your Services, Deployments, and other Kubernetes objects. If you already have definitions for your application, all you need to do is replace the generated YAML files for your own. What you end up with is a working chart that can be deployed using the helm install command.

It's worth noting, however, that the directory is named templates, and Helm runs each file in this directory through a Go template rendering engine. Helm extends the template language, adding a number of utility functions for writing charts. Open the service.yaml file to see what this looks like:


The template in service.yaml makes use of the Helm-specific objects .Chart and .Values. The former provides metadata about the chart to your definitions such as the name, or version. The latter .Values object is a key element of Helm charts, used to expose configuration that can be set at the time of deployment. The defaults for this object are defined in the values.yaml file. Try changing the default value for service.internalPort and execute another dry-run, you should find that the targetPort in the Service and the containerPort in the Deployment changes. The service.internalPort value is used here to ensure that the Service and Deployment objects work together correctly. The use of templating can greatly reduce boilerplate and simplify your definitions.

If a user of your chart wanted to change the default configuration, they could provide overrides directly on the command-line:

$ helm install --dry-run --debug ./mychart --set service.InternalPort=8080

Step 2. Deploying Your First Chart

So far in this tutorial, we've been using the helm install command to install a local, unpacked chart. However, if you are looking to share your charts with your team or the community, your consumers will typically install the charts from a tar package. We can use helm package to create the tar package:
$ helm package my-angular-project/

Helm will create a my-angular-project-0.1.0.tgz package in our working directory, using the name and version from the metadata defined in the Chart.yaml file. A user can install from this package instead of a local directory by passing the package as the parameter to helm install.


The chart you generated in the previous step is setup to run an our application exposed via a Kubernetes Service. By default, the chart will create a ClusterIP type Service, so the application will only be exposed internally in the cluster. To access it externally, we'll use the NodePort type instead. We can also set the name of the Helm release so we can easily refer back to it. Let's go ahead and deploy our application chart using the helm install command:

$ helm install my-angular-project-0.1.0.tgz

The output of helm install displays a handy summary of the state of the release, what objects were created, and the rendered NOTES.txt file to explain what to do next. Run the commands in the output to get a URL to access the angular-application service and pull it up in your browser.


If some changes have occurred in the image or application, they can be easily hardened using the helm upgrade:

$ helm upgrade killer-racoon my-angular-project-0.1.1.tgz

As a result, if we refresh the page in the browser, we will see modified application:

Back to blog