Launching a new course on Kubernetes: Check it out.

Create Ruby on Rails application using Docker

Thinking of creating a new Ruby on Rails application and possibly run it as container on Kubernetes, Amazon ECS, etc?

Below is a requirement of a Rails developer,

  • I need to create a new Ruby on Rails application. The new application will be built using new stable Ruby and Ruby-on-Rails versions. 
  • I have an older version of Ruby installed and my other Rails applications run on older versions. To create a new application with latest ruby and rails, I prefer not installing a new Ruby on my local machine or even install new rails gem
  • Application will use a specific version of MySQL and I have an older version of the MySQL installed on local that I use for other applications. Installing a new version might lead to conflicts or may not even work
  • I need an isolated environment for my new Rails application and its database setup. RVM or rbenv are options are a couple of options for Ruby part but not for MySQL setup
  • I have some experience in Docker but not a pro. Dockerizing an existing Rails application is straightforward but creating a new Rails project without an installed Ruby or Rails, seems a bit complicated. Need the get-started steps for creating a new Rails project using Docker.
In this article we will go over the steps involved in creating a new Ruby on Rails application using Docker.
 
Prerequisite: You need to have Docker Engine installed on your machine. I have Docker Desktop (Docker for Mac) installed. I have the Docker Desktop (Docker for Mac) installed on my machine; Docker version is 20.10.11 

Create project directory

				
					mkdir my-rails-app
cd my-rails-app
				
			

Create a project directory on your host machine. At the end of this article, we will have this directory with a Rails application code structure created.

Ruby Version

Before we create a Rails project using a specific Ruby, we should have an environment with that version of Ruby installed. I am going to use Ruby version 3.1.2.

Instead of installing Ruby on my machine, I will run a docker container using a Docker image containing Ruby 3.1.2 and then shell into the container.

				
					docker run --rm -it -v $PWD:/app:rw ruby:3.1.2 /bin/bash

> ruby -v
ruby 3.1.2p20 ...
>
> gem -v
3.3.7
>
> bundle -v
Bundler version 2.3.7
>
				
			

Let’s breakdown the docker command in the above snippet,

  • We run this command from inside the project directory my-rails-app and we mount the current directory to a path /app inside the container, with read-write (RW) permission. With this, when the container writes any files to /app those get written to the project directory my-rails-app on host
  • We use the Docker Image ruby:3.1.2 from DockerHub. When this container is run, we should be able to run any ruby commands inside the container
  • Last part of the command is /bin/bash . This instructs the docker engine to run the command /bin/bash inside the container when the container starts up. This is how you would shell into a new container
  • The option -i enables the interactive session with container shell. The option -t allocates puedo-TTY. The option –rm ensures the container is destroyed when we exit from the container shell.
Once we’re in the container shell, verify the ruby, bundler and gem by running the version commands. When you run exit on the container shell, not only it will end the session, it will stop and delete the container.

Install Rails Gem

We will be installing the Rails gem inside the container while we’re still on the container shell. Let’s run the gem install  …  command inside the container shell. If you exited from that shell, run the above docker run … command again.

				
					> gem install -v 7.0.3 --no-prerelease --no-document rails 

Fetching tzinfo-2.0.4.gem
...
...
Successfully installed actioncable-7.0.3
Successfully installed rails-7.0.3
35 gems installed
> 
> rails -v
Rails 7.0.3

				
			

We now have Rails 7 installed inside the container. If you exit from the container shell, you’ll lose this installation and you will have to run it again. That is because, on exiting the container shell the docker engine will delete the container and all its data.

Create a new project - Ruby on Rails

We are inside the container shell and the container has the project directory mounted (my-rails-app directory on the host machine to /app inside the container) with read-write permission to container. 

Let’s create a new Ruby on Rails project; provide the directory /app  as the project directory which maps to my-rails-app or the current directory where we ran docker run  command to shell into container

				
					> rails new --skip-bundle --database=mysql /app 

Initialized empty Git repository in /app/.git/
      create  app
      create  app/assets/config/manifest.js
      ...
      ...
      ...

> ls /app

Gemfile    Rakefile  bin     config.ru  lib  public   test  vendor
README.md  app       config  db         log  storage  tmp

				
			

It created a new rails project and the code is at /app . Because we have this folder /app mounted from my-rails-app directory from the host machine (Mac in my case), with read-write permission, we would expect the project directory structure with all the files/folders is actually written to my-rails-app. And the folders and files inside the my-rails-app directory should NOT be deleted if I exit from the container shell.

Let’s exit from the container shell and list the content of my-rails-app directory on host

				
					> exit 
exit
$
$
$ ls 
Gemfile         app             db              storage
Gemfile.lock    bin             lib             test
README.md       config          log             tmp
Rakefile        config.ru       public          vendor

$ 
				
			

So that is the Rails project structure created on the host using a docker.

Next Steps

Before we can run this new Rails application as a container, we need to do the following,

  • Create a Dockerfile that again uses the same docker image for ruby:3.1.2
  • Optionally, create a docker-compose.yml to supply the container with run-time configurations
  • Run a MySQL database as a container instead of installing a MySQL server on the host machine directly
  • Build the docker image for the rails application 
  • And, finally, run the application and build some cool stuff!
I’ve covered the above steps in detail in the following blog post: Dockerize An Existing Ruby on Rails Application. Please follow the instructions from that to complete setting up the docker environment for your new Rails application.

 

I hope you found this post helpful. I appreciate you sharing with your network that may find it useful.