Mac OS X 上の Docker で Ruby on Rails 用の開発環境つくってみた


## 前提

- Homebrew
- Virtualbox

## 導入

### Docker のインストール

DockerToolbox を入れようかと思ったけどアンインストールとかめんどくさそうなので Homebrew で個別に入れた。

```sh
brew install docker docker-compose docker-machine
```

### Docker Machine

```sh
docker-machine create default -d virtualbox
docker-machine start default
eval "$(docker-machine env default)"
```
最後の行は boot2docker が動いてる環境への接続情報を環境変数にセットしていて、別窓の端末とかだと以降の手順が動かないので注意。
めんどくさい場合は .zshrc とか .bashrc に `docker-machine env default` の実行結果をコピペする。

### NFS

Virtualbox を使うと共有フォルダがどうやっても遅すぎるので何とかする。
なんにしても無理矢理やるしかないので共有フォルダの代わりに NFS 使ってなんとかする方法をとった。
参考: https://gist.github.com/mattes/4d7f435d759ca2581347

```sh
ruby <(curl -L https://git.io/vvvco) default
```

他にも `rsync` を使ってる https://github.com/brikis98/docker-osx-dev も試したけど、環境によってうまく動かないことも多かったのでやめた。

## 設定

### Dockerfile とか

MySQL 使ったり MongoDB 使ったり ElasticSearch 使ったりで節操のないものを作ってしまったので大変だった

```docker:Dockerfile
FROM ruby:2.1-slim

RUN apt-get update -qq && apt-get install -y build-essential git libmysqlclient-dev libxml2-dev libxslt1-dev nodejs

ENV APP_HOME /myapp
RUN mkdir $APP_HOME
WORKDIR $APP_HOME

ADD Gemfile* $APP_HOME/
RUN bundle install

ADD . $APP_HOME
```

```yaml:docker-compose.yml
db:
  image: mysql
  environment:
    MYSQL_ROOT_PASSWORD: 'hogehoge'
  ports:
    - '3306:3306'
mongodb:
  image: mongo
  ports:
    - '27017:27017'
elasticsearch:
  image: 'brainskot/elasticsearch-kuromoji'
  ports:
    - '9200:9200'
fluentd:
  image: 'nacyot/td-agent'
redis:
  image: redis
  ports:
    - '6379:6379'
web:
  build: .
  command: bin/rails server -p 3000 -b 0.0.0.0
  ports:
    - '3000:3000'
  links:
    - db
    - mongodb
    - elasticsearch
    - redis
  volumes:
    - .:/myapp
  environment:
    DATABASE_PASSWORD: 'hogehoge'
```

```text:.dockerignore
.bundle
.git
db/*.sqlite3
db/*.sqlite3-journal
log/*.log
tmp
vendor/bundle
.DS_Store/
public/assets
```

### database.yml とか

環境変数とかを良い感じに読み込むようにする。こっちも無理矢理感否めない

```yaml:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: <%= ENV['DATABASE_PASSWORD'] || '' %>
  host: <%= ENV['DB_PORT_3306_TCP_ADDR'] || 'localhost' %>
  
development:
  <<: *default
  database: testapp_development
```

```yaml:config/mongoid.yml
development:
  sessions:
    default:
      database: testapp
      hosts:
        - <%= ENV['MONGODB_PORT_27017_TCP_ADDR'] || 'localhost' %>

```

```ruby:config/initializers/elasticsearch.rb
ENV['ELASTICSEARCH_URL'] ||= ENV['ELASTICSEARCH_PORT_9200_TCP_ADDR'] || 'localhost'
```

```ruby:config/initializers/sidekiq.rb
url = ENV['REDIS_PORT_6379_TCP_ADDR'].try {|u| "redis://#{u}" } || ENV['REDIS_URL'] || 'redis://localhost:6379'

Sidekiq.configure_server do |config|
  config.redis = { namespace: "testapp_#{Rails.env}", url: url }
end

# When in Unicorn, this block needs to go in unicorn's `after_fork` callback:
Sidekiq.configure_client do |config|
  config.redis = { namespace: "testapp_#{Rails.env}", url: url }
end
```

## 起動

初回はとても時間かかります。

```sh
docker-compose up
docker-compose run web rake db:create db:migrate db:seed
```

## 確認

あとは `docker-machine url dev` とか叩いて出てきたIPに :3000 をつけて動作確認。
便利コマンドを書いた↓

```sh
open $(docker-machine url default | sed -e 's/tcp/http/' -e 's/2376/3000/')
```