Kubernetes Tutorial: Running a Rails App in Kubernetes
Tags: kubernetes, ruby, rails, app
Published: 2021-04-22 06:54:58

---
title: Kubernetes Tutorial: Running a Rails App in Kubernetes
published: true
description: Wanna run Rails in Kubernetes? This Kubernetes Tutorial will show you how. We'll discuss Secrets Deployments Services Running locally via Minikube
tags: Kubernetes, Ruby, Rails, App
canonical_url: https://blog.engineyard.com/kubernetes-tutorial-running-a-rails-app-in-kubernetes?utm_source=Dev.to&utm_medium=Canonical-url
//cover_image: https://blog.engineyard.com/hs-fs/hubfs/RailsKubernetes.jpg?width=640&name=RailsKubernetes.jpg
---
By [Christopher Rigor](https://blog.engineyard.com/author/christopher-rigor)

As stated on their website, "Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications." Here we'll take a Rails app, create an image using a Dockerfile, and let Kubernetes manage the containers for us.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ka88usmvsz3l7pqd1f7.jpg)

We will discuss the following:

• Secrets
• Deployments
• Services
• Running locally via Minikube

## Wanna run Rails in Kubernetes? This Kubernetes tutorial will show you how.

#### Secrets

We'll start by creating a Kubernetes secret. This secret contains the secret key base and database credentials required by the Rails application. To generate a secret key base, run

<code> $ bundle exec rake secret
8d428e9d27e3323f1b1ec0089482017480224c9984fc10327f95b0990ec46175d43d756fd644c3bca3703a337a94ced69c868ab0470ac201cd1b6a80c3f89e4a </code>

Encode the secret key base using base64.

<code>$ echo -n "8d428e9d27e3323f1b1ec0089482017480224c9984fc10327f95b0990ec46175d43d756fd644c3bca3703a337a94ced69c868ab0470ac201cd1b6a80c3f89e4a" | base64
OGQ0MjhlOWQyN2UzMzIzZjFiMWVjMDA4OTQ4MjAxNzQ4MDIyNGM5OTg0ZmMxMDMyN2Y5NWIwOTkwZWM0NjE3NWQ0M2Q3NTZmZDY0NGMzYmNhMzcwM2EzMzdhOTRjZWQ2OWM4NjhhYjA0NzBhYzIwMWNkMWI2YTgwYzNmODllNGE=</code>

Next, encode the database credentials. Use the format DB_ADAPTER://USER:PASSWORD@HOSTNAME/DB_NAME. If you are using mysql with a user 'deploy' and a password 'secret' on 127.0.0.1 and have a database railsapp, run

<code>$ echo -n "mysql://deploy:secret@127.0.0.1/railsapp"
bXlzcWw6Ly9kZXBsb3k6c2VjcmV0QDEyNy4wLjAuMS90b2Rv</code>

Create a YAML file of the secret and save it anywhere in your local machine. You can use any filename. Here we use railsapp_secrets.yaml.

<code>apiVersion: v1
kind: Secret
metadata:
  name: railsapp-secrets
type: Opaque
data:
  secret-key-base: OGQ0MjhlOWQyN2UzMzIzZjFiMWVjMDA4OTQ4MjAxNzQ4MDIyNGM5OTg0ZmMxMDMyN2Y5NWIwOTkwZWM0NjE3NWQ0M2Q3NTZmZDY0NGMzYmNhMzcwM2EzMzdhOTRjZWQ2OWM4NjhhYjA0NzBhYzIwMWNkMWI2YTgwYzNmODllNGE=
  database-url: bXlzcWw6Ly9kZXBsb3k6c2VjcmV0QDEyNy4wLjAuMS90b2Rv</code>

#### Deployments

After creating the secret, we next create a deployment. A deployment contains the name of the image of your Rails app and the number of containers you want Kubernetes to run.

Deployments are used to rollout a new version of your app, rollback to a previous version, and to scale your app by running more containers.

You only need to change the values of "replicas" and "image". Notice we use the secrets we created earlier as environment variables. You should not put your credentials on your image and instead use a secret.

<code>apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: railsapp-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: railsapp
    spec:
      containers:
      - name: railsapp
        image: crigor/rails51:v6
        ports:
        - containerPort: 3000
        env:
          - name: DATABASE_URL
            valueFrom:
              secretKeyRef:
                name: railsapp-secrets
                key: database-url
          - name: SECRET_KEY_BASE
            valueFrom:
              secretKeyRef:
                name: railsapp-secrets
                key: secret-key-base</code>

If you do not have a Docker image on Docker Hub yet, check out the Dockerfile on our blog post on [Using Docker For Rails](https://blog.engineyard.com/using-docker-for-rails). It's important to set the app to log to standard out instead of a log file so that Kubernetes logging works.

You can name the yaml file railsapp_deployment.yaml.

#### Services

Lastly, you have to create a service to be able to access the app. We use the type NodePort on Minikube where Kubernetes will forward requests to a port on the Minikube VM to the application.

When using AWS I use the type LoadBalancer where Kubernetes will create an ELB that points to the 3 containers.

<code>kind: Service
apiVersion: v1
metadata:
  name: railsapp-service
spec:
  selector:
    app: railsapp
  type: NodePort
  #type: LoadBalancer
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 3000 </code>

Name the file railsapp_service.yaml.

#### Minikube
The instructions used here are for the Mac. If you have a different operation system, please refer to the [Minikube documentation](https://kubernetes.io/docs/tasks/tools/install-minikube/).

#### Install a Hypervisor

I use VirtualBox which you can download for free [here](https://www.virtualbox.org/wiki/Downloads).

#### Install kubectl

Download the kubectl and move it to your path.

<code>$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl</code>

#### Install Minikube

Download Minikube and move it to your path.

<code>$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.21.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/</code>

Feel free to leave off the sudo mv minikube /usr/local/bin if you would like to add minikube to your path manually.

#### Start Minikube

<code>$ minikube start
Starting local Kubernetes v1.7.0 cluster...
Starting VM...
Downloading Minikube ISO
97.80 MB / 97.80 MB [==============================================] 100.00% 0s
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Starting cluster components...
Connecting to cluster...
Setting up kubeconfig...
Kubectl is now configured to use the cluster.</code>

Check that kubectl can connect to the cluster with <code>kubectl version</code> and <code>kubectl cluster-info</code>.


#### Create the Kubernetes Objects

Now create the secret, deployment, and service from above.

<code>$ kubectl create -f railsapp_secrets.yaml
$ kubectl create -f railsapp_deployment.yaml
$ kubectl create -f railsapp_service.yaml</code>

Check the status.

<code>$ kubectl get secrets

NAME TYPE DATA AGE
default-token-9flwv kubernetes.io/service-account-token 3 2m
railsapp-secrets Opaque 2 45s

$ kubectl get deployments,pods

NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
railsapp-deployment 3 3 3 0 1m

NAME READY STATUS RESTARTS AGE
railsapp-deployment-1000337448-2qkpd 0/1 ContainerCreating 0 1m
railsapp-deployment-1000337448-9lrjc 0/1 ContainerCreating 0 1m
railsapp-deployment-1000337448-qnmlr 0/1 ContainerCreating 0 1m
</code>

You can see here that Kubernetes is still pulling the Docker image. When the image is ready and the containers are running you should see 3 under AVAILABLE on the deployment and Running under STATUS on the pods.

<code>e $ kubectl get services

NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.0.0.1 <none> 443/TCP 12m
railsapp-service 10.0.0.186 <nodes> 80:31596/TCP 1s<code>

#### Test the App

The app will be available on the Minkube IP and the node port of the service. To get the Minikube IP, run <code>minikube ip</code>. On my local machine, the app is available on 192.168.99.100:31596.

You can also run <code>minikube service railsapp-service</code> and Minikube will open the URL on your browser.

Conclusion
Kubernetes makes it easier to scale and manage applications. Kubernetes is a complex system but you can start with the basics - Secrets, Deployments, Services. With these 3, you can already start running your Rails application inside Kubernetes.

I've shown you how to run Rails on Kubernetes on your local machine via Minikube. In production, you can create a cluster say in AWS and still mostly the same Kubernetes secret (with different credentials), deployment, and service. We've only scratched the surface. If you want to hear more about Kubernetes and Rails, do let us know by leaving a comment.