Dockerize, Deploy and Run a Ruby on Rails application on Koyeb
Tags: docker, ruby, tutorial, webdev
Published: 2021-08-27 07:10:57

## Introduction

Ruby on Rails, or Rails, is a popular, server-side model-view-controller (MVC) web framework written in Ruby.
Rails provides all the features you need to build and maintain a modern web application.

Rails follows the convention over configuration philosophy meaning you write less code, and don't have to deal with tons of configuration files so you can focus on your application logic.

In this documentation, we will explain how to dockerize, deploy and run a Ruby on Rails application on the Koyeb serverless platform. By running your application on Koyeb, you natively benefit from
autoscaling, autohealing, TSL encryption, a Global Edge Network CDN, and more.

At the end of this guide, you will have a working Rails application containerized and running on Koyeb.

## Requirements

To successfully dockerize and run your Rails application on Koyeb, you need:
- Rails installed on your machine
- [Docker](https://docs.docker.com/get-docker/) installed on your machine
- A [Koyeb account](https://app.koyeb.com) to deploy and run the Rails application
- The [Koyeb CLI](https://www.koyeb.com/docs/cli/installation) installed to interact with Koyeb from the command line
- A registry that we will use to store our Rails web app Docker image and deploy it on Koyeb


## Steps

To successfully complete this guide to have a Rails application containerized and running on Koyeb, you need to follow these steps:

1. [**Create a new Rails application**](#create-a-new-rails-application)
2. [**Dockerize the Rails application**](#dockerize-the-laravel-application)
3. [**Push the Docker image to a container registry**](#push-the-docker-image-to-a-container-registry)
3. [**Deploy the Dockerized Rails app on Koyeb**](#deploy-the-dockerized-rails-app-on-koyeb)

## Create a new Rails application

*If you already have an existing Rails application that you want to dockerize and deploy on Koyeb, you can jump to the next step.*

To get started, we will create a basic Rails application using the new application generator. The command we will execute creates all the foundation of a fresh Rails application so that you don't have to write it yourself.

In your terminal, run the following command to create a new Rails application:

```bash
rails new demo
```

The command creates a demo directory and installs all the dependencies required to run the application. Once the initialization is done, go to the demo directory and add a new route to the router file `config/routes.rb` to handle request on `/`.

```ruby
Rails.application.routes.draw do
  root 'hello_world#index'
end
```

The route above is used to indicate GET / requests are mapped to the index action of HelloWorldController.
To create the HelloWorldController and its index action, run:

```bash
rails generate controller HelloWorld index --skip-routes
```

As you can see, we pass the `--skip-routes` as we don't want to generate a route for this controler as we previously manually created one.
Now, you can launch the development server running:

```bash
$rails server
=> Booting Puma
=> Rails 6.1.4 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.4.0 (ruby 2.6.1-p33) ("Super Flight")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 28869
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
```

Request on `/` will be handled by our HelloWorld controller. You can open a browser window and navigate to the `http://localhost:3000` URL. You land on the HelloWorld application page.


## Dockerize the Rails application

To Dockerize the Rails application, create a `Dockerfile` in your project root directory and copy the content below:

```dockerfile
FROM ruby:3-alpine
WORKDIR /app
COPY . .
RUN apk add --no-cache build-base tzdata nodejs yarn sqlite-dev postgresql-dev mysql-dev
RUN gem install bundler
RUN bundle install
ENV RAILS_ENV=production
RUN bundle exec rails assets:precompile
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
```

Build the Docker image by running:

```bash
docker build . -t ghcr.io/<GITHUB_USERNAME>/rails-app
```

*In this guide we will push the Docker image to the GitHub container registry. You are free to use another registry as Koyeb allows you to deploy from any container registry.*

Once the build is finished, you can run a container locally with the image to validate everything is working as expected using:

```bash
docker run -p 3000:3000 ghcr.io/<GITHUB_USERNAME>/rails-app
```

Your container should start and you can test the routes using curl:

```bash
curl localhost:3000/
```

## Push the Docker image to a container registry

Now that the Docker image is built and working properly, we can push it to a container registry. In this guide we will use the GitHub container registry. In your terminal run the command below to push the image:

```bash
docker push ghcr.io/<GITHUB_USERNAME>/rails-app
```

Your Docker image is now available on the GitHub container registry: `https://github.com/<YOUR_GITHUB_USERNAME>?tab=packages`.

## Deploy the Dockerized Rails web app on Koyeb

You can now deploy the dockerized Rails application on Koyeb. This section explains how to deploy on the Koyeb serverless platform using the CLI. This operation can also be performed using the [control panel](https://app.koyeb.com).

First, we need to create a Koyeb Secret containing the GitHub container registry configuration to deploy private images. In your terminal execute the following command and replace `<REPLACE_ME_WITH_GH_USERNAME>` with your GitHub username and `<REPLACE_ME_WITH_GH_TOKEN>` with a valid GitHub token having registry read/write permissions and execute the command below.

```bash
echo \
'{
  "auths": {
    "ghcr.io": {
      "username": "<GITHUB_USERNAME>",
      "password": "<GITHUB_TOKEN>"
    }
  }
}' | koyeb secrets create docker-hub-credentials --value-from-stdin
```

We can now deploy the Rails application on Koyeb Serverless Platform running:

```bash
koyeb app init rails-app --docker "ghcr.io/<REPLACE_ME_WITH_GH_USERNAME>/rails-app" --ports 3000:http --routes /:3000 --docker-private-registry-secret gh-registry-credentials
```

Within a few minutes, your application will be live and accessible at `https://rails-app-<KOYEB-ORG>.koyeb.app`.

## Conclusion

In this guide, we explained how to containerize, deploy and run a Rails application on Koyeb.
By deploying on Koyeb, your Rails application is secured with native TLS encryption and benefits from all the Koyeb serverless features including autoscaling, auto-healing, and a high-performance edge network.

If you have any questions or suggestions to improve this guide,
feel free to reach out to us on [Slack](https://slack.koyeb.com).