追記(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
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
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.development
のADD 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で環境構築をする場合は、設定事項は、環境変数で設定した方が簡単です。
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. spring
のbinstub
を作成する
以下のコマンドを実行します。
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
で
tty: true
stdin_open: true
を設定しています。これによって、pumaのサーバーの処理に挿入したbinding.pry
を使えるようになります。
docker ps
コマンドで、railsコンテナのコンテナ名を調べてください。
docker attach xxxx_rails_1 # xxxx_rails_1 は調べたコンテナ名
とすると、binding.pryをDockerの中で使えるようになります。
まとめ
Dockerの公式サイトでのチュートリアルでは、spring
を使った開発などが考慮されていないので使いにくいと思いました。
この手順で環境を構築するのもいいのではないかと思います。
アドバイスなどあれば是非お願いします!