久々に rails new したい欲求が高まったので、今風っぽく docker-compose を使って開発環境をつくります。
docker公式がドキュメントを用意してくれているので、まずはそれで感覚を掴んでみます。

Quickstart: Compose and Rails

OSはMac(Sierra)です。手元にあったdockerも少し古くなっていたので、アップグレードしつつ進めます。

1. Docker環境の準備

Install Docker for Mac からStable版のDockerをダウンロード・インストールします。
元々Docker Toolboxをインストールしていましたが、Docker for Macのインストーラーがよしなに差し替えたり調整してくれました。

詳しくは以下です。
Docker for Mac vs. Docker Toolbox

インストール後のバージョン確認

$ docker version
Client:
 Version:      17.06.0-ce
 API version:  1.30
 Go version:   go1.8.3
 Git commit:   02c1d87
 Built:        Fri Jun 23 21:31:53 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.06.0-ce
 API version:  1.30 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   02c1d87
 Built:        Fri Jun 23 21:51:55 2017
 OS/Arch:      linux/amd64
 Experimental: true

[bakunyo@wasta 01:04:10] ~
$ docker --version
Docker version 17.06.0-ce, build 02c1d87
[bakunyo@wasta 01:04:14] ~
$ docker-compose --version
docker-compose version 1.14.0, build c7bdf9e
[bakunyo@wasta 01:04:18] ~
$ docker-machine --version
docker-machine version 0.12.0, build 45c69ad

2. プロジェクトの定義

以下の4ファイルを作成します。

Dockerfile

FROM ruby:2.3.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp

Gemfile

source 'https://rubygems.org'
gem 'rails', '5.0.0.1'

Gemfile.lock
空でOK


docker-compose.yml

version: '3'
services:
  db:
    image: postgres
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

3. プロジェクトのビルド

ここからいよいよ docker-compose コマンドを使うので、軽く中身を確認しておきます。

docker-compose run
docker-compose up
docker-compose build

docker-compose.yml には複数のサービスが定義されていて、 run は特定のサービス、 up は全サービス(特定も可)に対する命令です。どちらも、コンテナが create & start されます。
また、 run は指定したサービス上で実行するコマンドを渡すことができ、 docker-compose.yml に書いてある command を上書きするみたいですね。

簡単ですが以上を踏まえて、以下のコマンドを実行した後の流れを見ていきます。

$ docker-compose run web rails new . --force --database=postgresql

流れの確認

  • デフォルトネットワークを生成
  • run web なのでサービス[web]の起動が始まる
  • depend_on: db となっている為、サービス[db]を先に起動する
    • postgresのimageをpull & dbサービス用のネットワークを生成
  • build: . なので Dockerfile を元にコンテナを生成する
    • ruby:2.3.3 からimageをpull
    • RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
      • 必要なライブラリのインストール
    • RUN mkdir /myapp
    • WORKDIR /myapp
    • ADD Gemfile /myapp/Gemfile
    • ADD Gemfile.lock /myapp/Gemfile.lock
    • RUN bundle install
      • WORKDIRを指定しているので、 /myapp/Gemfile を元にインストールが始まる
    • ADD . /myapp
  • docker-compose run の引数に渡しているコマンドが実行される
    • rails new . --force --database=postgresql
    • コマンドが上書きされているので、 rails s は実行されない
    • --force オプションで、 Gemfile が上書きされる

4. 再ビルド

$ docker-compose build

Gemfileが書き換わったので、imageを再ビルドします。
rails new のとき --skip-bundle しても良さそうですね。

5. DB設定

config/database.yml を以下に書き換え

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test

host: db で接続できるということですね。便利!

6. サーバー起動

サービスを起動します。

$ docker-compose up

別のターミナルを開き、以下を実行します。

$ docker-compose run web rake db:create

http://localhost:3000 にアクセスします。

ちゃんと起動していました!
Docker環境さえあれば、たった数ファイルでここまで構築できるってすごいですね。
大体の流れは掴めたので、これをベースに自分用にカスタマイズしていこうと思います。