Getting Started With Helm 3 Using React and Codefresh
Tags: devops, docker, helm, kubernetes
Published: 2020-10-27 17:22:46

Helm is an application package manager for Kubernetes. Using Kubernetes can often be overwhelming to maintain resources. Since Kubernetes is configured by YAML files, the more complex your application becomes, the more difficult it will be to navigate and make changes to the respective files; think about lots and lots of repetitive YAML files. A scenario that makes every developer cringe. Helm can help you solve this.

This blog post will explain what Helm is, how it works, and provide a walkthrough of how you can set-up your first Helm chart.
<h3>Helm Overview</h3>
Helm allows users to define a common blueprint for an application or a selection of microservices on a Kubernetes cluster through Helm templates. Helm templates describe the resources of your application. They will generate manifest files, which Kubernetes can understand to install and run your application. The combination of Helm templates and according values is called a Helm chart.

Each release goes through multiple stages, including its installation, upgrade, removal, and rollback. With Helm, you can group multiple microservices together and treat them as one entity. You can either create your own chart or use an existing one from <a href="https://artifacthub.io/">Helm</a> Artifact Hub. Once your application is packaged into a Helm chart, it can easily be shared and deployed on Kubernetes.

A lot of the criticism of Helm is based on Helm 2. However, Helm made several major changes between Helm 2 and Helm 3, namely:
<ul>
 	<li>No more Tiller: Helm 2 had to be used in combination with Tiller which got a lot of criticism for its access-control;</li>
 	<li>Release information is now by default stored in Secrets: to retrieve release information Helm can simply access the secret, decrypt it, and apply it. This is why Tiller is not needed anymore.</li>
 	<li>Namespaces are not automatically created for releases: Helm 3 follows kubecl naming conventions by throwing an error message if you attempt to create a release where the namespace does not exist;</li>
 	<li>JSON Schema Chart Validation: allowing maintainers to set-up a JSONSchema to define specific value types on a chart, the validation tool is automatically be run on helm install/unpgrade/lint.</li>
</ul>
Several features and specifications of Helm are optional or can be customized based on your project’s needs and your preferences. If you are familiar with Helm 2 but not 3, you might want to check those out. Also, Helm 2 will no longer receive security updates from November 13th onwards.

We will not look at the differences between Helm versions in this tutorial. If you are curious whether Helm is the right fit for your project, I recommend having a look at <a href="https://codefresh.io/helm-best-practices-guide/">our e-book</a>.

<h3>Alternatives to Helm</h3>
There are several Helm alternatives that provide templating options to manage Kubernetes resources. However, just templating is often not enough to manage the complexity of Kubernetes.

One widely promoted alternative is Kubernetes Operators. An Operator is a method of packaging, deploying, and managing a Kubernetes application. Thus, both Helm and Kubernetes Operators are sometimes used interchangeably to automate tasks. However, they are actually quite different.

Both tools are supposed to be used for different purposes. Helm set out to be the package manager for Kubernetes. In comparison, Operators are meant to translate user-knowledge into reusable code to extend and automate processes. Thus, as <a href="https://github.com/technosophos">Matt Butcher</a>, the creator of Helm, <a href="https://cloudblogs.microsoft.com/opensource/2020/04/02/when-to-use-helm-operators-kubernetes-ops/">puts it</a>:

“Helm is a package manager for Kubernetes. Operators are design-pattern-driven pieces of code that encapsulate knowledge for running an application. Yet (...), there are questions floating around about which one is ’the winner.’”

A lot of the confusion between Helm and Kubernetes Operators is based on the same terminology being used for different processes. For instance, when Helm users talk about installing something, they usually mean finding and installing a chart that, with little configuration, can manage their application resources. In contrast, using Kubernetes Operators, the conversation is usually around creating a Kubernetes YAML that manages and maintains an application.

Deciding between both, or using both in combination, is largely dependent on the type of application that you want to manage.

<h3>Getting started with Helm</h3>
This tutorial will provide a step-by-step guide on how you can set-up your first Helm chart for your project; taking you from Helm installation to deploying the chart and setting up a Codefresh pipeline.

<b>Prerequisites</b>
<ul>
 	<li>Please make sure to have access to a Kubernetes cluster. For the first half of the tutorial <a href="https://minikube.sigs.k8s.io/docs/start/">minikube</a> or <a href="https://microk8s.io/">microk8s</a> are sufficient. If you are not sure which one to use, have a look at <a href="https://codefresh.io/kubernetes-tutorial/local-kubernetes-linux-minikube-vs-microk8s/">this tutorial</a>.</li>
 	<li>Kubernetes command-line tool —<a href="https://kubernetes.io/docs/tasks/tools/install-kubectl/"> kubectl</a>.</li>
</ul>

<strong>Installing Helm</strong>

Helm provides multiple <a href="https://helm.sh/docs/intro/install/">installation options</a>. We are on Ubuntu and are going to use snap to install Helm:
<code>sudo snap install helm --classic</code>

However, you could also use an existing package manager, such as Homebrew or Chocolatey, or install from the Binary Release, Source, or Script.

<strong>Setting up your first Helm Chart</strong>

We will base our Helm Chart on this <a href="https://github.com/anais-codefresh/react-article-display/tree/react-template-project">React App</a>. To follow the tutorial, you could either
<ul>
 	<li>clone the App and do exactly what we do,</li>
 	<li>apply the steps to your own NodeJS App,</li>
 	<li>or apply and adapt the steps to your own application, using the steps here as a reference.</li></ul>
The decision is up to you.

<b>Set-up Dockerfile</b>

We will be using a Docker Image of our application in our Helm Chart. Follow the next steps to create your Dockerfile.

For the Dockerfile, we are using a multi-stage-build to combine multiple builds in a single Dockerfile. You can read more on multi-stage-builds on the <a href="https://codefresh.io/docker-tutorial/docker-multi-stage-builds/">Codefresh blog</a>.

In your main project folder, create the Dockerfile:

<code>touch Dockerfile</code>

Open the file and either copy and paste the following <a href="https://github.com/anais-codefresh/react-article-display/blob/helm-3-tutorial/Dockerfile">Dockerfile</a> into your own Dockerfile or modify the content in accordance with your needs. Please have a look at the comments provided for further information.

<pre>
# Pull official base image

FROM node:14.9.0 as build-deps

# A directory within the virtualized Docker environment

# Becomes more relevant when using Docker Compose later

WORKDIR /usr/src/app

# Copies package.json and package-lock.json to Docker environment

COPY package.json yarn.lock ./

# Installs all node packages

RUN npm install

# Copies everything over to Docker environment

COPY . ./

# Installs all node packages

RUN npm run build

# the base image for this is an alpine based nginx image

FROM nginx:1.19-alpine

# copy the build folder from react to the root of nginx (www)

COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html

# expose port 80 to the outer world

EXPOSE 80

# start nginx

CMD ["nginx", "-g", "daemon off;"]
</pre>

Note our .<a href="https://github.com/anais-codefresh/react-article-display/blob/helm-3-tutorial/.dockerignore">dockerignore</a> file, referencing the files and folders that will be ignored by the Docker daemon. Read more about<a href="https://codefresh.io/docker-tutorial/not-ignore-dockerignore-2/"> the importance of dockerignore</a> and how you can optimise your Docker images with the right specifications.

Before we are going any further, we will want to make sure that our Dockerfile set-up works. For this we are using the following command to build the Docker image:

<code>docker build -t <name of your docker image> . </code>

If you are using the same Dockerfile, you should expect an output similar to the one provided below:
<a href="https://codefresh.io/wp-content/uploads/2020/10/docker-image-build.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/docker-image-build.png" alt="docker-image-build" width="807" height="516" class="size-full wp-image-17805" /></a>

If you have received any error messages, please resolve those first before moving on to the next step.

Once we have built the Dockerfile, we can run the following command to access our application:

<code>docker run -it --rm -p 3001:80 <name of your docker image> </code>

Then you can open the application on http://localhost:3001/.

Lastly, we want to publish our Docker image to a public registry. In our case, we are going to use the Docker Hub. However, you could also use another registry, such as the <a href="https://codefresh.io/docker-registry/github-container-registry/">Github Container Registry</a>. The choice is yours.

Log-into Docker:

<code>docker login</code>

Push your image:

<code>docker push <name of your docker image> </code>

<b>Set-up Helm Chart</b>

Next, we will set-up the Helm chart. This tutorial will use the <a href="https://codefresh.io/docs/docs/new-helm/using-helm-in-codefresh-pipeline/">Codefresh documentation</a> to set-up a Helm chart with the <code>helm create</code> command.
<ol>
 	<li>Set-up a chart folder in your main repository: <code>mkdir charts</code></li>
 	<li>Change into the charts folder: <code>cd charts</code></li>
 	<li>Run the Helm command to create a chart template: <code>helm create example-chart</code></li>
</ol>
This will create the following directory in your main repository:

<pre>
charts/example-chart/

templates/         # the chart template

charts/         # any chart dependencies

.helmignore         # files to ignore

Chart.yaml          # meta-information about the chart

Values.yaml         # default values for the chart template
</pre>

To use our own application repository instead of the default repository provided, we have to replace the default repository and tag inside the values.yaml with our repository name.

<pre>image:

repository: anaisurlichs/react-article-display </pre>

All of our template files receive values from the values.yaml file. We will run the following command to access the template content in a format that is easier to read:

<code>helm install --dry-run --debug example-chart ./charts/example-chart</code>

Note, make sure that you are in the right project folder.

This will tell you the status of your chart install and return the computed values, hooks, and manifest:
<a href="https://codefresh.io/wp-content/uploads/2020/10/chart-output.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/chart-output.png" alt="helm chart output" width="339" height="121" class="size-large wp-image-17806" /></a>

Once we verified that all the values are correct, we can run the following command to install our chart:

<code>helm install example-chart ./charts/example-chart</code>
<a href="https://codefresh.io/wp-content/uploads/2020/10/installing-example-chart.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/installing-example-chart.png" alt="installing-example-chart" width="938" height="175" class="size-large wp-image-17807" /></a>

The chart installation will set-up a pod in your Kubernetes cluster automatically. Now verify that your pod has been set-up and runs:

<code>helm ls</code>

<a href="https://codefresh.io/wp-content/uploads/2020/10/running-the-helm-ls-command.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/running-the-helm-ls-command.png" alt="running-the-helm-ls-command" width="1255" height="84" class="size-large wp-image-17808" /></a>

To access our application from the Kubernetes cluster, we can either follow the steps displayed in the terminal from our NOTES.txt file, or forward the port from the pod to our local port:

<code>kubectl port-forward <name of the pod> 3000:80</code>

In our case, the name of the pod would be example-chart-76c5d469f5-5t5nx; you can check the pod name by running

<code>kubectl get pods</code>

Now visit localhost:3000 and you should see your application running from within the Kubernetes Cluster 🎉
<a href="https://codefresh.io/wp-content/uploads/2020/10/running-application.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/running-application.png" alt="running-application" width="1290" height="823" class="size-large wp-image-17809" /></a>

<h3>Combining Helm with Codefresh</h3>
Imagine running all the commands manually every time to make changes to your app. Our goal is to make this easier for you using Codefresh pipelines.

Codefresh includes comprehensive built-in support for Helm charts, building Docker images, and pushing them to Docker registries. Additionally, it even offers a private &amp; free Helm repository with each account. Combined with a dedicated Kubernetes dashboard, Codefresh is a one-stop-shop for microservice development.

This section will show you how to set-up your Codefresh pipeline to make the best out of Helm.

<b>Set-up codefresh.yml file </b>

First, we will set-up our codefresh.yml file. The codefresh.yml file is used to build your Codefresh pipeline and allows you to customize the build steps in your pipeline. There are two ways that you could set-up the codefresh.yml file. Namely,
<ul>
 	<li>Create the pipeline from scratch;</li>
 	<li>Use the auto-generated pipeline as a starting point.</li>
</ul>
For the purpose of this tutorial, we will follow the first option and define our codefresh.yml file in our project folder.

To set-up the codefresh.yml file please run the following command in your main project folder:

<code>touch codefresh.yml</code>

Our <a href="https://github.com/anais-codefresh/react-article-display/blob/master/codefresh.yml#L2">codefresh.yml</a> file will use the <a href="https://codefresh.io/docs/docs/getting-started/create-a-basic-pipeline/">minimum set-up</a> for this project but feel free to <a href="https://codefresh.io/docs/docs/codefresh-yaml/what-is-the-codefresh-yaml/">dive deeper</a> and add <a href="https://codefresh.io/docs/docs/codefresh-yaml/steps/freestyle/">freestyle steps</a> in accordance with your needs.

<pre>{% raw %}
version: "1.0"
 
stages:
 - "clone"
 - "build"
 - "test"
 - "deploy"
 steps:
 clone:
   title: "Cloning repository"
   type: "git-clone"
   repo: "anais-codefresh/react-article-display"
   revision: "${{CF_BRANCH}}"
   git: "github"
   stage: "clone"
 
 build:
   title: "Building Docker image"
   type: "build"
   image_name: "anaisurlichs/react-article-display"
   working_directory: "./react-article-display"
   tag: "${{CF_BRANCH_TAG_NORMALIZED}}"
   dockerfile: "Dockerfile"
   stage: "build"
{% endraw %}</pre>

Please make sure to adapt the following keys to your project:
<pre>
image_name: "your Docker image name goes here"

working_directory: "change to your working directory"
</pre>

Please add the following in your codefresh.yml file to use the Helm charts that you have defined in the previous step.

<pre>{% raw %}
deploy:
   type: "helm"
   working_directory: "./react-article-display"
   arguments:
     action: "install"
     chart_name: "charts/example-chart"
     release_name: "example-chart"
     helm_version: 3.0.2
     kube_context: "anais-cluster@codefresh-sa"
   stage: "deploy"
{% endraw %}</pre>

For tutorial purposes, we will install the Helm chart directly from the filesystem of our pipeline. Usually you would first push the Helm chart to your Helm repository and then install.

Make sure that your chart_name is pointing to the chart name in your main repository, in our case this is “charts/example-chart”, and that your kube_context states the Kubernetes cluster <a href="https://codefresh.io/docs/docs/deploy-to-kubernetes/add-kubernetes-cluster/">connected to your Codefresh account</a> that you will be using. If you do not have a Kubernetes cluster connected to Codefresh, now is the time to do that.

Next, we will push all of our changes to our GitHub repository. Once this is done, we will set-up our Codefres pipeline.
<ol>
 	<li>In your Codefresh account, select “New Project” from the top right of your Dashboard in the projects tap:</li>
<a href="https://codefresh.io/wp-content/uploads/2020/10/codefresh-new-project.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/codefresh-new-project.png" alt="codefresh-new-project" width="1219" height="507" class="aligncenter size-full wp-image-17810" /></a>
 	<li>Next, follow the instructions to create your project.</li>
 	<li>Once you created your project, you will be redirected to your project section in your Dashboard:</li>
<a href="https://codefresh.io/wp-content/uploads/2020/10/project-dashboard.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/project-dashboard.png" alt="project-dashboard" width="1226" height="695" class="aligncenter size-large wp-image-17811" /></a>
 	<li>Go ahead and create a pipeline for your project. Assuming that you are connected with your GitHub account to Codefresh, it will ask you to select the repository that you want to create the pipeline for. Once you have provided the information, you will be redirected to the workflow, which displays the auto-generated codefresh.yml file. In our case, we will use the YAML from our repository instead.</li>

<a href="https://codefresh.io/wp-content/uploads/2020/10/inline-yml.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/inline-yml-300x212.png" alt="inline-yml" width="300" height="212" class="size-medium wp-image-17812" /></a>
 	<li>Hit run at the bottom of the screen; which will direct you to the Codefresh step. You can follow the processing through the command line. Once done, you will see the output of our NOTES.txt file.</li>
<a href="https://codefresh.io/wp-content/uploads/2020/10/codefresh-pipeline-1.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/codefresh-pipeline-1-1024x483.png" alt="codefresh-pipeline" width="1024" height="483" class="size-large wp-image-17813" /></a> 
 	<li>Now the Helm chart is deployed to our Kubernetes Cluster using the Codefresh pipeline. To view the Helm Chart, access Helm &gt; Releases within DEVOPS INSIGHTS. You should see something similar to the following. If not, please make sure that you have selected the right Helm version and Kubernetes cluster in the settings.</li>
<a href="https://codefresh.io/wp-content/uploads/2020/10/view-helm-chart.png"><img src="https://codefresh.io/wp-content/uploads/2020/10/view-helm-chart-1024x198.png" alt="view-helm-chart" width="1024" height="198" class="size-large wp-image-17814" />
</ol>

<h3><b>Summary</b></h3>
In this tutorial, we have looked at Helm, the difference between Operators and Helm to manage your Kubernetes cluster, and we set up our first Helm Chart. You should now have gathered a fundamental understanding of Helm and how you can use it to manage your Kubernetes resources. Additionally, if you followed the entire tutorial, you got your Codefresh pipeline up and running. Congratulations!

Please let us know in the comments whether this tutorial was helpful, you have any questions, suggestions, or useful links for the community to learn more about Helm.

New to Codefresh?  <a href=”https://codefresh.io/codefresh-signup/?utm_source=Blog&utm_medium=Post&utm_campaign=helmstarter”>Create Your Free Account today</a>!