Scaling Ruby on Rails Applications: Techniques and Tools for Optimizing Performance - Part 4 (Horizontal Scaling)

Horizontal scaling is the process of adding more servers to handle increased traffic and user activity in your Ruby on Rails application. With horizontal scaling, you can handle more requests by distributing the load across multiple servers, rather than relying on a single server to handle all the traffic. In this article, we will discuss how to implement horizontal scaling in Ruby on Rails, with a code example.

To implement horizontal scaling in Ruby on Rails, we will use a containerization technology called Docker. Docker is a popular tool for containerizing applications, which allows us to package our application and its dependencies into a container image that can be run on any server.

Here is an example of how to implement horizontal scaling in Ruby on Rails using Docker:

Install Docker on your development machine or server.

Create a new Ruby on Rails application using the rails new command.

Create a new Dockerfile in the root directory of your application with the following contents:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Dockerfile

FROM ruby:2.7.4

RUN apt-get update && apt-get install -y build-essential libpq-dev nodejs

WORKDIR /app

COPY Gemfile Gemfile.lock ./

RUN bundle install --jobs 20 --retry 5

COPY . .

CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]

In this Dockerfile, we are using the official Ruby 2.7.4 image as the base image. We are also installing build-essential, libpq-dev, and nodejs packages, which are required for building native extensions and running JavaScript assets. We then copy the Gemfile and Gemfile.lock files to the container and run bundle install to install the application’s dependencies. Finally, we copy the entire application code to the container and set the CMD to start the Rails server.

Create a new docker-compose.yml file in the root directory of your application with the following contents:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# docker-compose.yml

version: '3.8'
services:
  app:
    build: .
    command: bundle exec rails server -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - '3000:3000'
    environment:
      DATABASE_URL: postgres://postgres:password@db:5432/app_development
    depends_on:
      - db
  db:
    image: postgres:12.7
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: app_development

volumes:
  pgdata:

In this docker-compose.yml file, we define two services: app and db. The app service is built using the Dockerfile in the current directory, and we set the command to start the Rails server. We also map port 3000 from the container to port 3000 on the host machine, so we can access the application from a web browser. We set the DATABASE_URL environment variable to connect to the db service, which runs a PostgreSQL database. Finally, we define a volumes section to persist the database data.

Start the application using the docker-compose up command. This will build the Docker image and start the containers.

To scale the application horizontally, run the docker-compose up –scale app=3 command. This will start three instances of the app service, which will be load balanced automatically by Docker.

In conclusion, horizontal scaling is an essential technique for handling increased traffic and user activity in Ruby on Rails applications. Using tools like Docker Compose, you can easily deploy and scale your application infrastructure, allowing you to handle more requests without slowing down.