Ukraine is at WAR with Russia now! World history being written these days - become one who was involved! Your grandchildren would love to hear the stories!

Слава Україні! Glory to Ukraine!

Sometimes we want to play with the new version of Ruby/Rails, but in order to do so we need to install dependencies which quite often is not so seamless. So let’s take a look how to use Docker and shell commands in order to quickly start new project with any combination of Ruby/Rails version and keep the macOS itself clean as a baby’s bottom.

TL;DR - Gist

Process step-by-step

The overall process is quite straightforward and consists of seven dependent steps

  1. Create a folder for a project on local drive
  2. Create Gemfile with ruby/rails version within this folder
  3. Create configuration for Docker within this folder
  4. Build a Docker image
  5. Install rails non the new container
  6. Create new rails project from Docker image with files stored on the local drive
  7. Start the server

Now let’s take a look at each step in detail:

Step #1 - Create a folder for a project on local drive

export DOCKER_RAILS_VERSION="7.0.1"
export DOCKER_RUBY_VERSION="3.1.0"
mkdir app
cd app

the folder will be named /app and all new files will be added inside

Step #2 - Create Gemfile with ruby/rails version within this folder

echo "ruby '$DOCKER_RUBY_VERSION'
source 'https://rubygems.org'
gem 'rails', '$DOCKER_RAILS_VERSION'" > Gemfile

this step is done only for the convenience - we will use bundler later to install correct version of the rails gem

Step #3 - Create configuration for Docker

First we create folder where configuration files will live

mkdir .devcontainer
cd .devcontainer

next we add Dockerfile that will be used later by Docker Compose to build our image

echo "FROM ruby:$DOCKER_RUBY_VERSION-slim
RUN apt-get update \
 && apt-get install -y make gcc git sqlite3 libsqlite3-dev \
 && rm -rf /var/lib/apt/lists/*" > Dockerfile

we add gcc, git, sqlite3, libsqlite3-dev packages in order to be able to compile gems later

I’m using slim version of the ruby image from Docker, you can read more about the difference between images in Alpine, Slim, Stretch, Buster, Jessie, Bullseye — What are the Differences in Docker Images? by Julie Perilla Garcia

Now let’s take a closer look at different pieces of docker-compose.yml

...
services:
  web:
...

this is the beginning of our service, it will be named web

...
    build:
      context: .
      dockerfile: Dockerfile
...

this section will tell the Docker Compose to use the Dockerfile within app/.devcontainer/ to build an image

...
    volumes:
      - "$(pwd)/..":/web:cached
    working_dir: /web
...

we will mount parent directory app/ to the image as /web and set it as a default directory for work, :cached part is added to improve the performance of bind-mounted directories on macOS

...
    command: sleep infinity
...

this will keep the container running indefinitely

...
    environment:
      - BUNDLE_PATH=vendor/bundle
...

this is done in order to keep installed gems within the /app/vendor/bundle folder and not install them every time we start the container

...
    ports:
      - '3000:3000'" > docker-compose.yml

here we expose port from container 3000 to macOS

Step 4 - Build a Docker image

docker-compose up -d --build

this command will build an image and start the container, -d is for detached mode, --build to build image before starting container

Step 5 - Install rails in the new container

docker-compose exec web bundle

web is the name of the service where bundle command will be executed, by default it will be run in the web/ folder inside container, that is app/ folder on the macOS drive, where we created Gemfile at Step 2

Step 6 - Create new rails project

docker-compose exec web bundle exec rails new . -f

this will create new rails application inside app/ folder and overwrite existing Gemfile

Step 7 - Start the server

docker-compose exec web bundle exec rails s -b 0.0.0.0

you have to start the server at 0.0.0.0 in addition to the port exposing to make things work

Now if you navigate to http://localhost:3000 you should see the default rails page

Extra

Ukraine is at WAR with Russia now! World history being written these days - become one who was involved! Your grandchildren would love to hear the stories!

Слава Україні! Glory to Ukraine!

image: ruby-$DOCKER_RUBY_VERSION-rails-$DOCKER_RAILS_VERSION

this will add a tag to container with information on ruby/rails version

Don’t forget to stop the container with docker-compose down

If Gemfile does not exist in the web/ folder:

  • stop all containers
  • delete any built images
  • restart Docker
  • start from the Step 1

Revisions

  • Mar 06, 22