dockerをつかってrailsの開発をしてみる


[railsアプリをDocker化してみる - Qiita](http://qiita.com/eielh/items/bb68b45845ae1d3304ec)でアプリだけDocker化するのはさほど難しくないという話をした。
この場合はDBは既存のものが使えるから気軽に使えそうという話をした。

今回はDockerだけでRails開発をしてみようと思う。
HerokuのデフォルトがPostgreSQLなのでPostgreSQLを例にする。

# Railsプロジェクトの作成

rails new をしよう。

```
docker run --rm -it -v "$(pwd)":/usr/src/app -w /usr/src/app rails rails new hello -d postgresql
```

Dockerがインストールされていればrubyなんていらない。
Windowsでも戦えそうだが試してない。
夢が広がる。

しかし、`rails rails new`というのはなんだか格好悪い。

ちゃんとローカルのファイルシステムに作成されている。

```
$ cd hello
$ tree .
.
├── Gemfile
├── Gemfile.lock
├── README.rdoc
├── Rakefile
├── app
│   ├── assets
│   │   ├── images
│   │   ├── javascripts
│   │   │   └── application.js
│   │   └── stylesheets
│   │       └── application.css
│   ├── controllers
│   │   ├── application_controller.rb
│   │   └── concerns
│   ├── helpers
│   │   └── application_helper.rb
│   ├── mailers
│   ├── models
│   │   └── concerns
│   └── views
│       └── layouts
│           └── application.html.erb
├── bin
│   ├── bundle
│   ├── rails
│   ├── rake
│   ├── setup
│   └── spring
├── config
│   ├── application.rb
│   ├── boot.rb
│   ├── database.yml
│   ├── environment.rb
│   ├── environments
│   │   ├── development.rb
│   │   ├── production.rb
│   │   └── test.rb
│   ├── initializers
│   │   ├── assets.rb
│   │   ├── backtrace_silencers.rb
│   │   ├── cookies_serializer.rb
│   │   ├── filter_parameter_logging.rb
│   │   ├── inflections.rb
│   │   ├── mime_types.rb
│   │   ├── session_store.rb
│   │   └── wrap_parameters.rb
│   ├── locales
│   │   └── en.yml
│   ├── routes.rb
│   └── secrets.yml
├── config.ru
├── db
│   └── seeds.rb
├── lib
│   ├── assets
│   └── tasks
├── log
├── public
│   ├── 404.html
│   ├── 422.html
│   ├── 500.html
│   ├── favicon.ico
│   └── robots.txt
├── test
│   ├── controllers
│   ├── fixtures
│   ├── helpers
│   ├── integration
│   ├── mailers
│   ├── models
│   └── test_helper.rb
├── tmp
│   └── cache
│       └── assets
└── vendor
    └── assets
        ├── javascripts
        └── stylesheets

38 directories, 40 files

```

# データベースサーバを起動

```
docker run -d --name hello-db postgres
```

`rails new` するとき hello という名前にしたので hello-db という名前にした。

停止したくなったら

```
docker stop hello-db
```

再開する時は

```
docker start hello-db
```

いらなくなったら(当然データは消える)

```
docker rm hello-db
```

# 開発用イメージの作成

開発時にrailsを実行するためのイメージをつくる。
つまり、Dockerfileをかく。

```Dockerfile
FROM rails:onbuild

ENV DB_USER postgres
ENV DB_PASSWORD password
ENV DB_NAME hello
ENV DB_ADAPTER postgres
ENV DATABASE_URL ${DB_ADAPTER}://${DB_USER}:${DB_PASSWORD}@db/${DB_NAME}
```

そうしたらこのDockerfileを基にイメージを作成しよう。

```
docker build -t hello .
```

イメージの名前はhelloにした。
このコマンドはGemfileを書き換えたときは実行する。

現実的には`.dockerignore`をかいておいたほうがよい。

# rails serverの起動

イメージができたので起動して`bin/rails s`をすればよい。
他のコマンドも実行しやすいように bash で起動してから操作するのもありだと思う。

```
docker run --rm -it -p 3000:3000 -v $(pwd):/usr/src/app --link hello-db:db hello bash
bin/rake db:create db:migrate
bin/rails s -b 0.0.0.0
```

boot2dockerを利用している場合はIPの確認をしよう。

```
boot2docker ip
```

http://xxx.xxx.xx.xx:3000/ にでもアクセスすれば動作していることが確認できると思う。
適当にscaffoldなどしてみるとよいと思います。

`bin/rails s`していたのとCtrl+cでとめて

```
bin/rails g scaffold bookmark name:string url:string
bin/rake db:migrate
bin/rails s
```

http://xxx.xxx.xx.xx:3000/bookmarks にでもアクセスしてみればよいです。

ローカルのファイルシステムのファイルも更新されているのことを確認してみると良いと思います。

あとはCIでイメージつくったり、CIでイメージ内でテストしたりすると幸せになれそうな気がする。

# コマンドの長さに耐えられない

[fig](http://www.fig.sh/)を使いましょう。
Macであれば`brew install fig`でインストールできます。

figを使う場合は`fig.yml`を作成します。

```fig.yml
db:
  image: postgres
  ports:
    - "5432"
web:
  build: .
  command: bin/rails s -b 0.0.0.0
  volumes:
    - .:/usr/src/app
  ports:
    - "3000:3000"
  links:
    - db
```

あとは`fig up`を実行します。
railsのコマンドを使いたい場合は

```
fig run web rails g scaffold name:string url:string
```

のように`fig run web`の後にコマンドを続けます。

蛇足: figを使わずシェルスクリプトでなんとかしている例がこの記事の過去のバージョンに記述しています。興味があればみてみてください。

# まとめ

Docker楽しい。
しかし、イメージのダウンロードがつらい。

ついでに、githubにアップしておいた。

dockerが使える状態にしてあれば、

```
git clone https://github.com/eiel/docker-rails-develop-sample.git
cd docker-rails-develop-sample
fig up
fig run bin/rake db:setup
```

で動作確認ができるんじゃないだろうか。
boot2dockerを使用している場合は`boot2docker ip`でIPを確認してください。