(Updated) Use docker-compose to develop a Ruby on Rails application
Using docker-compose to develop a Rails application
You can find the code for this tutorial on my Github repository.
In order to kickstart the application we need to install the rails gem and run the rails new <appname> command. We will do this inside the same Docker container that will be used to run the application itself. To do so we need to create a Dockerfile to create the Docker image with the necessary dependencies, a docker-compose.yml file to provision the other services needed (a postgres database and a volume store) and a Gemfile (with an empty Gemfile.lock) to install the rails gem and bundle install its dependencies.
Create a new directory and some empty files:
mkdir rails-docker-compose
cd rails-docker-compose
touch Dockerfile docker-compose.yml Gemfile Gemfile.lockCopy and paste the following content in the respective files:
File Dockerfile
FROM ruby:2.4.2
ENV APP_ROOT /app
ENV BUNDLE_PATH /usr/local/bundle
RUN apt-get update -qq && \
apt-get install -y build-essential libpq-dev nodejs
WORKDIR $APP_ROOT
ADD . $APP_ROOTFile docker-compose.yml
version: '3'
volumes:
store:
driver: local
bundle:
driver: local
services:
web:
build: .
ports:
- 3000:3000
volumes:
- .:/app
- bundle:/usr/local/bundle
links:
- db
# Keep the stdin open, so we can attach to our app container's process and do things such as
# byebug, etc:
stdin_open: true
# Enable sending signals (CTRL+C, CTRL+P + CTRL+Q) into the container:
tty: true
command: ./bin/start.sh
environment: &app_env
PORT: 3000
DB_HOST: db
DB_PORT: 5432
DB_USER: postgres
DB_PSWD: postgres
DB_NAME: development_database
db:
image: postgres:latest
ports:
- 5432:5432
volumes:
- store:/var/lib/postgresql/data
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: development_databaseFile Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 5'Build the project
First we need to bundle the rails 5 dependencies:
docker-compose run --rm web bundle --jobs=10 --retry=5And then use the rails new command to create the new application:
docker-compose run --rm web bundle exec rails new . --force --database=postgresql --skip-bundleConfigure the database
We need to change slightly the database configuration to use the environment variables set in the docker-compose file:
File: config/database.yml
default: &default
adapter: postgresql
encoding: unicode
username: <%= ENV['DB_USER'] %>
password: <%= ENV['DB_PSWD'] %>
host: <%= ENV['DB_HOST'] %>
# For details on connection pooling, see rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: <%= ENV['DB_NAME'] %>
test:
<<: *default
database: test_databaseSetup the app
docker-compose run --rm web bin/setupCreate a start.sh file in the bin dir:
File: bin/start.sh
#!/bin/bash
bundle check || bundle install
if [ -f tmp/pids/server.pid ]; then
rm -f tmp/pids/server.pid
fi
bundle exec rails s -p $PORT -b 0.0.0.0It automatically removes the server.pid that will create problems when you stop
and restart the app.
Make the file executable with the chmod command:
chmod +x bin/start.shFinally start your newly created Rails application and visit localhost:3000:
docker-compose up