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

  • 88
    いいね
  • 1
    コメント

追記(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