The Rails framework is a popular choice with developers who want to create web applications with ease. It is based on the Ruby language and it allows you to write less code with its predefined layout and additional libraries for simplifying the programming of web applications.

If you have chosen Docker as the platform for building your Rails application image, what could be the next step? Running your application in a production environment. Kubernetes is the best way for running application deployments across clusters of hosts. This solution allows you to automate the deployment, the scaling and management of application containers.

To more easily deploy and manage the application containers in a Kubernetes cluster, you can use Helm charts. In the same way that a Dockerfile contains instructions on how to build images in running containers, the charts define how the application will be deployed in Kubernetes. They specify the objects definitions, services, dependencies, number of pods, and so on.

This guide walks you through the process of running an example Rails application on a Kubernetes cluster. It uses a simple “Hello World!” Rails application based on the latest Bitnami Rails image. The next step is to create a Dockerfile and use it as a starting point for creating a custom Helm chart to automate the application deployment in a Kubernetes cluster. Once the application is deployed and working, this guide also explores how to modify the source code for publishing a new application release and how to perform rolling updates in Kubernetes using the Helm CLI.

Prerequisites

This guide will show you how to deploy an example Rails application in a Kubernetes cluster running on Minikube. The example application is a typical “Hello World!” application.

This guide makes the following assumptions:

  • You have basic knowledge of how to build Docker images.
  • You have basic knowledge of Helm charts and how to create them.
  • You have a Docker environment running.
  • You have Minikube installed in your local computer.
  • You have a Kubernetes cluster running.
  • You have the kubectl command line (kubectl CLI) installed.
  • You have Helm v3.x installed.

To create your own application in Rails and deploy it in a Kubernetes cluster using Helm you will typically follow these steps:

  • Step 1: Create the Helm Chart
  • Step 2: Deploy the example application in Kubernetes

Step 1: Create The Helm Chart

It is very easy to get started with Helm charts by using the helm create command. It creates a scaffold with sample files that you can modify to build your custom chart. The following instructions will take you through the process of creating a new chart and customizing it to include your Rails sample application.

  • In the same directory you are working in, execute the helm create command to create a new chart named my-rails-app:
$ helm create my-rails-app
  • Change to my-rails-app directory:
$ cd my-rails-app
  • Helm will have created a directory with the file structure shown below:
my-rails-app
|-- Chart.yaml
|-- charts
|-- templates
|   |-- NOTES.txt
|   |-- _helpers.tpl
|   |-- deployment.yaml
|   |-- ingress.yaml
|   `-- service.yaml
`-- values.yaml
  • Edit the values.yaml file and replace the existing values with the following:
# Default values for my-rails-app.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: USERNAME/my-rails-app
tag: 0.1.0
pullPolicy: IfNotPresent
service:
name: http
type: NodePort
externalPort: 80
internalPort: 3000
resources:
limits:
    cpu: 100m
    memory: 128Mi
requests:
    cpu: 100m
    memory: 128Mi
values.yaml
  • Edit the templates/deployment.yaml file to add the database environment variables as shown below:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "fullname" . }}
labels:
    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
spec:
replicas: {{ .Values.replicaCount }}
template:
    metadata:
    labels:
        app: {{ template "fullname" . }}
    spec:
    containers:
    - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - containerPort: {{ .Values.service.internalPort }}
        env:
        - name: MARIADB_HOST
        value: {{ template "mariadb.fullname" . }}
        - name: SKIP_DB_WAIT
        value: "1"
        - name: MARIADB_PASSWORD
        valueFrom:
            secretKeyRef:
            name: {{ template "mariadb.fullname" . }}
            key: mariadb-root-password
        resources: {{ toYaml .Values.resources | indent 12 }}
        livenessProbe:
        httpGet:
            path: /
            port: {{ .Values.service.internalPort }}
        initialDelaySeconds: 180 # We need to wait for the database initialization
        timeoutSeconds: 5
        readinessProbe:
        httpGet:
            path: /
            port: {{ .Values.service.internalPort }}
        initialDelaySeconds: 60
        timeoutSeconds: 5
templates/deployment.yaml
  • Edit the templates/_helpers.tpl file and append these lines at the end of the file:
{{/*
Create a default fully qualified app name.
We truncate at  63 | trimSuffix "-" chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "mariadb.fullname" -}}
{{- printf "%s-%s" .Release.Name "mariadb" | trunc  63 | trimSuffix "-" -}}
{{- end -}}
templates/_helpers.tpl
  • Your file should look like this:
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at  63 | trimSuffix "-" chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "mariadb.fullname" -}}
{{- printf "%s-%s" .Release.Name "mariadb" | trunc  63 | trimSuffix "-" -}}
{{- end -}}
templates/_helpers.tpl
  • In the my-rails-app/ parent folder, create a new file named requirements.yaml that includes the following content:
dependencies:
- name: mariadb
version: 0.6.0
repository: https://kubernetes-charts.storage.googleapis.com/
requirements.yaml
  • Install missing dependencies with helm dep. The Helm chart used in this guide includes MariaDB dependencies specified in the recently-created requirements.yaml file. So you need to download and install them before deploying the application. Execute the commands below to finish creating the chart:
$ helm dep list
$ helm dep update .
  • Test that the syntax of the files is correct by running the helm lint command:
$ helm lint .

Step 2: Deploy The Example Application In Kubernetes

At this point, you have created your custom Helm chart. It’s now time to deploy the example Rails application within a Kubernetes cluster.

To deploy the example application using the current Helm chart, follow these steps:

  • First, make sure that you are able to connect to your Kubernetes cluster by executing the command below:
$ kubectl cluster-info
  • Deploy the Helm chart with the helm install command. This will create two pods within the cluster, one for the Rails service and the other for the MariaDB service. DB-PASSWORD is a placeholder, replace it with the password of the root user used during the database creation.
$ helm install --set mariadb.mariadbRootPassword=DB-PASSWORD my-rails-app .


Once the chart has been installed, you will see a lot of useful information about the deployment.