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.
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.
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.
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.
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!