Ruby on rails Kubernetes deployment with razorops CI/CD

Created by Saurabh Singh Singh Yadav, Modified on Thu, 14 Sep, 2023 at 3:46 PM by Shyam Mohan K

Table of Content:

  • Introduction
  • Understand Dockerfile 
  • Understand Helm files
  • Local testing
  • Manual deployment
  • Setup CI/CD pipeline
  • Understand .razorops.yaml file
  • In Action 


This guide focuses on achieving a complete end-to-end setup of a Ruby on Rails (RoR) project using Helm chart and Razorops. It assumes that Kubernetes is already set up, so Kubernetes setup won't be covered in this guide.

 

The first crucial step in deploying a web application on Kubernetes is containerization. Containerization involves understanding the Dockerfile and the structure of a typical RoR project, which includes a Dockerfile and a helm folder.


|-- Dockerfile
|-- Gemfile
|-- Gemfile.lock
|-- Procfile
|-- Procfile.dev
|-- README.md
|-- Rakefile
|-- app
|-- bin
|-- config
|-- config.ru
|-- db
|-- dump.rdb
|-- helm
|-- lib
|-- log
|-- package-lock.json
|-- package.json
|-- public
|-- storage
|-- test
|-- tmp
|-- vendor
`-- yarn.lock

Understand Dockerfile


FROM ruby:3.0.0-slim

RUN apt-get update -qq && apt-get install -yq --no-install-recommends \
    build-essential \
    gnupg2 \
    libpq-dev \
    git \
    curl \
  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq && apt-get install -y build-essential nodejs yarn

ENV LANG=C.UTF-8 \
  BUNDLE_JOBS=4 \
  BUNDLE_RETRY=3 \
  RAILS_ENV=production \
  RAILS_SERVE_STATIC_FILES=true

RUN gem update --system && gem install bundler

WORKDIR /usr/src/app

COPY Gemfile* ./

RUN bundle config frozen true \
 && bundle config jobs 4 \
 && bundle config deployment true \
 && bundle config without 'development test' \
 && bundle install

COPY package.json yarn.lock ./
RUN yarn install --check-files

COPY . .

# Precompile assets
# SECRET_KEY_BASE or RAILS_MASTER_KEY is required in production, but we don't
# want real secrets in the image or image history. The real secret is passed in
# at run time
RUN cp config/database.example.yml config/database.yml
ENV SECRET_KEY_BASE=fakekeyforassets
RUN bin/rails assets:clobber \
  && bundle exec rails assets:precompile 

EXPOSE 3000

CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

This Dockerfile sets up a container environment for a Ruby on Rails application, specifically targeting version 3.0.0 of Ruby. Here are the main points explained concisely:


  • The base image is Ruby version 3.0.0 with the slim variant, which provides a smaller image size.
  • The necessary dependencies are installed, including build-essential, gnupg2, libpq-dev, git, curl, nodejs, and yarn.
  • Environment variables are set, including language encoding, the number of parallel workers for Bundler, Rails environment, and serving static files.
  • The Gemfile and package.json files are copied to the working directory, and the necessary gems and Node.js dependencies are installed using bundle install and yarn install.
  • The application files are copied to the working directory.
  • The assets are precompiled by running bin/rails assets:clobber and bundle exec rails assets:precompile.
  • Port 3000 is exposed to allow incoming connections.
  • The default command to run when the container starts is bundle exec puma -C config/puma.rb, which starts the Puma web server.


We can test this docker file by building and running it locally to ensure everything is working as expected there can be different dependencies like database, redis etc. so to test it locally either we can use docker compose or local kubernetes to run these services along side with main application and test. 


Understand Helm files


When deploying an application on Kubernetes, we need manifest YAML files that Kubernetes understands. However, standalone YAML files are not inherently reusable. To promote reusability and extendibility, we utilize Helm charts.


Helm charts serve as package managers for Kubernetes, similar to npm or pip in programming languages. They provide a structured way to package Kubernetes resources, including YAML files, along with configurable values. With Helm charts, we can define reusable templates, parameterize values, and manage dependencies. This allows for easier application deployment, configuration, and management in Kubernetes environments.


The helm chart folder structure consists of several files and subdirectories:

helm
|-- Chart.lock
|-- Chart.yaml
|-- charts
|   |-- postgresql-12.6.3.tgz
|   `-- redis-17.11.7.tgz
|-- templates
|   |-- NOTES.txt
|   |-- _helpers.tpl
|   |-- cert.yaml
|   |-- common-cm.yaml
|   |-- common-secret.yaml
|   |-- db-backup.yaml
|   |-- deployment.yaml
|   |-- hpa.yaml
|   |-- ingress.yaml
|   |-- migrate-job.yaml
|   |-- service.yaml
|   |-- serviceaccount.yaml
|   `-- worker.yaml
`-- values.yaml


Chart.lock: This file contains the lock information for the chart dependencies, including their versions, ensuring consistent deployment across different environments.


Chart.yaml: This file contains the metadata and configuration details for the helm chart, such as the chart name, version, description, and dependencies.


charts/: This directory contains packaged dependency charts, such as postgresql and redis, in the form of .tgz files.


templates/: This directory contains the template files that define the Kubernetes resource manifests for deploying the application. Some notable files include:

NOTES.txt: This file typically contains instructions or information displayed after a successful deployment.

_helpers.tpl: This file contains helper functions and variables used in other template files.

cert.yaml: This file defines resources related to certificates, such as TLS secrets.

common-configmap.yaml: This file defines a ConfigMap that holds common configuration data.

common-secret.yaml: This file defines a Secret that holds common secrets, such as API keys or database credentials.

db-backup.yaml: This file defines a backup job for the database.

deployment.yaml: This file defines the deployment resource for the main application.

hpa.yaml: This file defines the Horizontal Pod Autoscaler resource, which automatically scales the application based on resource utilization.

ingress.yaml: This file defines an Ingress resource, which allows external access to the application.

migrate-job.yaml: This file defines a job that performs database migrations.

service.yaml: This file defines a Kubernetes Service resource for the main application.

serviceaccount.yaml: This file defines a ServiceAccount resource, which provides permissions for the application.

worker.yaml: This file defines resources related to worker processes, such as deployment and service.

values.yaml: This file contains the default configuration values for the chart. It allows customization of various parameters when deploying the chart.


The helm chart folder structure organizes the necessary files and directories to package and deploy the application using Helm, a package manager for Kubernetes.


Let's understand important files, here I will explain the important and relevant files and will try to draw the relation between the Dockerfile


This rails-sample-app/helm/templates/deployment.yaml files contains the instruction to deploy our ror app on k8s.



...
      containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: {{ .Values.app.port }}
              protocol: TCP
...



Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons

Feedback sent

We appreciate your effort and will try to fix the article