Bootstrapping new Rails application without installing Ruby locally
This guide shows and explains bootstrapping new Rails application using Docker. This way you don’t have to install Ruby and other tools on your host.
In my case I want to use PostgreSQL as a default database. The magic command is:
docker run --rm -v $PWD:/app -w /app ruby:2.5.1-alpine /bin/sh -c 'apk add --update build-base postgresql-dev && gem install rails -v "5.2.0" && rails new . --database=postgresql'
How does it work?
Let’s break the command down into parts:
docker run
- this creates a new Docker container--rm
- remove the image after runningrails new
-v $PWD:/app
- mount current directory in/app
-w /app
- set default work directory to/app
ruby:2.5.1-alpine
- image identifier of a ruby official repository image tagged as2.5.1-alpine
. 2.5.1 refers to the Ruby version.alpine
is a lightweight Linux distribution that weights only around 5MB./bin/sh -c '...'
- a command to run in the Docker container. We need to run multiple commands (combined with&&
). The only way to achieve that is to run them in a shell. We usesh
instead ofbash
because by default Alpine doesn’t have bash installed.apk add --update build-base postgresql-dev
- installs Rails and pg gem (used for PostgreSQL) dependenciesgem install rails -v "5.2.0"
- installs Railsrails new . --database=postgresql
- bootstraps Rails application using Postgres as default DB. Finally!
Interactive rails new
If you want to experiment with rails new
parameters you can use an interactive shell instead.
docker run --rm -it -v $PWD:/app -w /app ruby:2.5.1-alpine /bin/sh
Please notice new docker option: -it
. These are two separate options: -i
(also--interactive
) and -t
(also --tty
). Usually you want to use them together when running anything interactive.
Custom application name
rails new
required PATH
argument not only determines the path but also is used to set the application name.
The app name is used in config/application.rb
to define a top module.
Unfortunately for some reason it’s not possible to provide application name as an option.
To work around this issue use custom volume mountpoint and absolute path of current directory instead of .
docker run --rm -v $PWD:/$(basename $PWD) -w /$(basename $PWD) ruby:2.5.1-alpine /bin/sh -c 'apk add --update build-base postgresql-dev && gem install rails -v "5.2.0" && rails new $PWD --database=postgresql'
File permissions in Linux host volumes
If you are using a Linux host to run Docker all files created by rails new
are owned by root on your local machine.
The problem is fixable using sudo chown
but it’s just a temporary solution. The only permit solution is to use user namespace that will help you with remapping your host user to Docker.
My post about Linux user namespaces shows how to fix this properly.
This problem doesn’t exist on Mac OS or Windows where NFS is used to mount local volumes.