Thinking of creating a new Ruby on Rails application and possibly run it as container on Kubernetes, Amazon ECS, etc? If so, do your requirements align with the following:

  • I want to create a new Ruby on Rails application and build it using the latest stable Ruby and Ruby on Rails
  • I currently have an older version of Ruby installed for my other Rails applications and do NOT want to install a new version directly on my work machine for the new application
  • The new app will use a specific version of MySQL, and I already have an older version of MySQL installed on my local machine for other applications. Installing a new version may lead to conflicts or may not work at all
  • I require an isolated environment for my new Rails application and its database setup. While options such as RVM or rbenv exist for the Ruby portion, but I still need to solve for running multiple versions of MySQL servers
  • I have some experience in Docker but not a pro. Dockerizing an existing Rails application seems straightforward but creating a new Rails project without a specific Ruby or installed Rails, seems a bit complicated. I need a Get Started guide on creating a new Rails project using Docker

If your requirements align with the above, this post will guide you through creating a new Rails application using Docker without installing Ruby or Rails directly on your OS.

Prerequisite: Ensure that you have Docker Engine installed on your machine. I have Docker Desktop (Docker for Mac) installed on my machine; Docker version is 20.10.11

UPDATE: Check out this new short course on Dockerizing Rails Development Environment using Docker & DevContainers extension in VSCode.

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, this directory will contain a Rails application code files & folders.

Ruby Version

Before we create a Rails project using a specific Ruby version, 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 or on OS directly, 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 docker run ... command,

  • 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 that 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 an interactive session with container shell. The option -t allocates puedo-TTY. The option –-rm ensures that the container is destroyed when we exit from the container shell

Once we’re inside the container shell, you may verify the ruby, bundler, gem, etc. And when you’re done, just type exit to end the session and that should 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. However, 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

Now that we are inside the container shell, let’s create a new Ruby on Rails app; provide the directory /app as the project directory which maps to the current project directory, my-rails-app, 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 inside the container. Because we have /app mounted from my-rails-app directory on the host machine, with read-write permissions, 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

$

This is how you can create the Rails project structure using Docker, without having to install specific versions of Ruby or Rails on your work machine.

Next Steps

To run this new Rails application as a container, there are a few things we need to do first:

  • Create a Dockerfile that uses the same Docker image for ruby:3.1.2
  • Optionally, create a docker-compose.yml file to provide the container with run-time configurations
  • Run a MySQL database as a container instead of installing a MySQL server directly on the host machine
  • Build the Docker image for the Rails application
  • Finally, run the application and build some amazing things!

If you need more details on these steps, I’ve covered them in the following blog post titled Dockerize An Existing Ruby on Rails Application.” Now that Rails project has been created, one should be able to follow the same instructions to Dockerize and Run as docker containers.