DEV Community

Bohdan Pohorilets
Bohdan Pohorilets

Posted on • Originally published at bpohoriletz.github.io on

[EN] Rails 7 application inside Docker on macOS - part one

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

echo "version: '3.8'
...

Enter fullscreen mode Exit fullscreen mode

this is the Compose file format version, you can find more information about this file and available versions at Docker Docs

...
services:
  web:
...

Enter fullscreen mode Exit fullscreen mode

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

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

Enter fullscreen mode Exit fullscreen mode

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

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

this will keep the container running indefinitely

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

here we expose port from container 3000 to macOS

Step 4 - Build a Docker image

docker-compose up -d --build

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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 createdGemfile at Step 2

Step 6 - Create new rails project

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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:3000you should see the default rails page

Extra

image: ruby-$DOCKER_RUBY_VERSION-rails-$DOCKER_RAILS_VERSION

Enter fullscreen mode Exit fullscreen mode

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

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

#docker

Stories about Docker as a technology (containers, CLI, Engine) or company (Docker Hub, Docker Swarm).

Top comments (0)