Posted at

DockerでRailsを開発するためのファーストステップ

More than 3 years have passed since last update.

ある環境では動いていたのに、他の人の環境では動かなくなってしまったり、複数のプロジェクトに関わっていて、あるアプリケーションをアップグレードしたら、こっちのプロジェクトで動かなくなってしまう事が多々ありました。

gemとかであればbundlerがうまい具合に環境の差異を吸収してくれるのですが、ネイティブのライブラリを使い始めると、はまることが多くなってきます。

例えば、PostgreSQLのバージョンを9.4にアップグレードしたら、昔のプロジェクトが動かなくなってなってしまったりとか。

そこで、Dockerを使ってプロジェクト毎に環境を用意するようにすれば、そういったはまりが減らさせると思い使ってみることにしました。

Mac OS XでRailsをDocker上で動かすためのセットアップ手順をまとめときたいと思います。


Dockerをインストール

下記を参照にインストールします。

http://docs.docker.com/installation/mac/

CUIかGUIがあるようですが、CUIの手順でインストールしていきます。GUIの場合は、Kitematicというのをいれるみたいですね。



  1. boot2docker/osx-installerからパッケージをダウンロードします。

  2. "Downloads"セクションから'Boot2Docker-x.x.x.pkg'をクリックしダウンロードします。

  3. ダウンロードしたパッケージをダブルクリックしてインストールします。

これでBoot2DockerとVirtualBoxが"アプリケーション"フォルダーにインストールされます。

ターミナルを開いて、

1) 新しくBoot2Docker VMを作成します。

$ boot2docker init

これでVirtualBoxに仮想マシーンを作成します。

2) boot2docker VMを起動します。

$ boot2docker start

3) Dockerクライアントの環境変数を表示します。

$ boot2docker shellinit

Writing /Users/mary/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/mary/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/mary/.boot2docker/certs/boot2docker-vm/key.pem
export DOCKER_HOST=tcp://192.168.59.103:2376
export DOCKER_CERT_PATH=/Users/mary/.boot2docker/certs/boot2docker-vm
export DOCKER_TLS_VERIFY=1

上記の出力はお使いの端末によって異なります。

4) お使いのシェルに環境変数をセットするには以下を実行します:

$ eval "$(boot2docker shellinit)"

私の場合はzshを使っているので、手動で上記のコマンドで出力された環境変数の箇所を~/.zshrcの最後に以下を追加します。


~/.zshrc

export DOCKER_HOST=tcp://192.168.59.103:2376

export DOCKER_CERT_PATH=/Users/mary/.boot2docker/certs/boot2docker-vm
export DOCKER_TLS_VERIFY=1

5) hello-worldコンテナを実行してセットアップがちゃんとできてるかどうか確認します。

$ docker run hello-world


Docker Composeのインストール

Docker Composeを使うことで複数のコンテナを効率よく管理することができます。例えば、Railsを動かすコンテナとPostgreSQLを動かすためコンテナを複数立ち上げて、それらを統一されたコマンドで操作することができます。

次のコマンドを実行してインストールします。

$ curl -L https://github.com/docker/compose/releases/download/1.3.3/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

$ chmod +x /usr/local/bin/docker-compose

もし、アクセス権がなくて失敗してしまう場合は、sudo -iをして上記のコマンドを実行してexitします。


Railsのセットアップ

最後に以下を参照にしてにRails環境をセットアップしていきます。

http://docs.docker.com/compose/rails/

Composeを使ってRails/PostgreSQLの環境を構築します。


プロジェクトの定義

プロジェクトに3つのファイルを準備します。

まず、Dockerのコンテナに必要な依存関係を定義したDockerfileを作成します。


Dockerfile

FROM ruby:2.2.2

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
RUN bundle install
ADD . /myapp

ここでは、コンテナ上にRuby, Bundlerを構築する記述をしておきます。

次に、コンテナを構築した際にbundle installを実行するので、その際にRailsをインストールするようにGemfileを用意しておきます。これは、後ほどrails newを実行した際に上書きされます。

source 'https://rubygems.org'

gem 'rails', '4.2.3'

最後に、docker-compse.ymlを用意して、データベースとwebアプリを構成します。

db:

image: postgres
ports:
- "5432"
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
links:
- db


プロジェクトの構築

docker-compose runコマンドを経由して、Railsのひな形を生成します。

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

最初に、ComposeはDockerfileをベースにweb用のをイメージを構築します。それから、その中新しいコンテナの中でrails newを実行します。実行が完了すると、新しくRailsのアプリが生成されていることを確認できます。

$ ls

Dockerfile app docker-compose.yml tmp
Gemfile bin lib vendor
Gemfile.lock config log
README.rdoc config.ru public
Rakefile db test

Gemfiletherubyracerのコメントアウトを外します。

gem 'therubyracer', platforms: :ruby

Gemfileが更新されたので、イメージを構築し直します。

$ docker-compose build


データベース接続

データベースはdbというホスト名で動作する様に設定しています。rails newで生成したデフォルトでは、DBサーバはlocalhostで動作しているのを想定しているので、設定を変更します。また、postgresイメージで設定しているユーザ名に変更します。

config/database.ymlを編集します。

development: &default

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

test:
<<: *default
database: myapp_test

これでアプリを起動します。

$ docker-compose up

そうすると、いくつかのPostgreSQLの起動に関する出力に続いて、railsサーバの起動を確認できます。

myapp_web_1 | [2014-01-17 17:16:29] INFO  WEBrick 1.3.1

myapp_web_1 | [2014-01-17 17:16:29] INFO ruby 2.2.0 (2014-12-25) [x86_64-linux-gnu]
myapp_web_1 | [2014-01-17 17:16:29] INFO WEBrick::HTTPServer#start: pid=1 port=3000

最後に、別のターミナルを立ち上げてDBを作成します。

$ docker-compose run web rake db:create

以上で、boot2docker ipを実行したipに接続してRailsアプリが起動しているのを確認できます。