Docker で Rails5 の開発環境を「rails new」から構築する

More than 1 year has passed since last update.


追記(2017/02/13)

以下の方法では、Gemfileを修正するたびにDockerイメージをビルドし直す必要がありますが、もっと高速に開発できるテンプレートを作成しました。

高速に開発できる Docker + Rails開発環境のテンプレートを作った


はじめに

Dockerを使ってRails5の開発環境を構築します。

また、railsコマンドをspringを通して実行できるようにします。

rails new から rails db:createまで、すべてをDockerの上で行うことを目指して構築します。

また、実際のコードはこちらにアップロードしています。


環境

私の手元の環境は、OS X で行いましたが、基本的にDockerが使えればできます。


手順


1. rails new する環境を作成する

以下のファイルを作ります。


  • Dockerfile.development

  • docker-compose.yml

  • Gemfile

  • Gemfile.lock


Dockerfile.development


Dockerfile.development

FROM ruby:2.3.1

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install -j4
ADD . /app



docker-compose.yml


docker-compose.yml

version: '2'

services:
rails: &app_base
build:
context: .
dockerfile: "Dockerfile.development"
command: "bundle exec rails s -p 3000 -b '0.0.0.0'"
environment:
- "DATABASE_HOST=db"
- "DATABASE_PORT=5432"
- "DATABASE_USER=postgres"
- "DATABASE_PASSWORD=mysecretpassword1234"
volumes:
- ".:/app"
ports:
- "3000:3000"
links:
- db
tty: true
stdin_open: true
spring:
<<: *app_base
command: "bundle exec spring server"
ports: []
tty: false
stdin_open: false
db:
image: "postgres:9.5"
environment:
- "POSTGRES_USER=postgres"
- "POSTGRES_PASSWORD=mysecretpassword1234"
volumes_from:
- data
data:
image: "busybox"
volumes:
- "/var/lib/postgresql/data"


Gemfile

source 'https://rubygems.org'

gem 'rails', '5.0.0'


Gemfile.lock

Gemfile.lock は、Dockerfile.developmentADD Gemfile.lock /app/Gemfile.lock を実行させるために空のファイルを作ります。

touch Gemfile.lock


2. rails new する

rails new します。今回は、APIモードでrails new してみました。オプションはそれぞれのケースに合わせて選ぶと良いと思います。

docker-compose run --rm rails rails new . --force --database=postgresql --skip-bundle --skip-test --api


3. Gemfile を修正し、Gemfile.lockを更新する

Gemfileをお好みで修正し、Gemfile.lockを生成します。

Gemfile.lockは以下のコマンドで更新されます。

docker-compose run --rm rails bundle install

また、Gemfile.lockを更新した後は、Dockerのイメージを更新する必要があります。

docker-compose build

今回は、pry-railsなどを追加してみました。

source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '5.0.0'
# Use postgresql as the database for Active Record
gem 'pg', '~> 0.18'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# gem 'rack-cors'

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug'
gem 'bullet'
gem 'factory_girl_rails'
gem 'pry-rails'
gem 'pry-byebug'
end

group :development do
gem 'listen', '~> 3.0.5'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
gem 'annotate'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]


4. database の設定を行う

databaseの設定を行います。

config/database.yml を修正した後に、以下のコマンドでデータベースの初期化を行います。

docker-compose run --rm rails rails db:create


config/database.yml

Dockerで環境構築をする場合は、設定事項は、環境変数で設定した方が簡単です。


config/database.yml

default: &default

adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch('DATABASE_USER') { 'root' } %>
password: <%= ENV.fetch('DATABASE_PASSWORD') { 'password' } %>
host: <%= ENV.fetch('DATABASE_HOST') { 'localhost' } %>
port: <%= ENV.fetch('DATABASE_PORT') { 5432 } %>

development:
<<: *default
database: app_development

test:
<<: *default
database: app_test

production:
<<: *default
database: app_production



5. springbinstubを作成する

以下のコマンドを実行します。

docker-compose run --rm rails bundle exec spring binstub --all


6. 完成

以上で完成です。実際に環境を立ち上げてうまく表示されることを確認しましょう。

docker-compose up

open http://$(docker-machine ip):3000


7. 本番環境のDockerfileを作る

本番環境ではよりスリムなイメージを作りたいと思います。開発環境では、Dockerfile.developmentを利用しているので、本番環境では、Dockerfileを作成してビルドするレシピを書けば、開発環境と本番環境のイメージを別にすることができます。


開発を進めるには


spring でコマンドを高速実行

spring コンテナーを作成しているので、rails コマンドをspringを利用して高速に実行できます。

例えば、rails db:migrateを実行するには

docker-compose exec spring rails db:migrate

を実行するとdockerコンテナー内で実行されます。


binding.pry を使う

docker-compose.yml


docker-compose.yml

    tty: true

stdin_open: true

を設定しています。これによって、pumaのサーバーの処理に挿入したbinding.pry を使えるようになります。

docker ps

コマンドで、railsコンテナのコンテナ名を調べてください。

docker attach xxxx_rails_1 # xxxx_rails_1 は調べたコンテナ名

とすると、binding.pryをDockerの中で使えるようになります。


まとめ

Dockerの公式サイトでのチュートリアルでは、springを使った開発などが考慮されていないので使いにくいと思いました。

この手順で環境を構築するのもいいのではないかと思います。

アドバイスなどあれば是非お願いします!


参考URL