DockerでWindows機のメンバーのRails環境セットアップ（Herokuプロジェクト）

# はじめに
Windowsを使っているデザイナーさんにRailsプロジェクトのcssをいじってもらうために環境を作らなければならなくなり、Railsのセットアップをやってもらうのはハードルが高いなあと思い、初めてDockerに挑戦してみることにしました。

## 前提
heroku上にある既存のRailsプロジェクトをwindows環境で実行できるようにします。

- ruby2.3.1
- rails5.0
- postgresql
- heroku

## Dockerについて
Dockerについてははこちらの記事を読むとDockerのことがざっとわかると思います。
[2016年版、Dockerのすべてが5分でわかるまとめ!(コマンド一覧付き)](http://paiza.hatenablog.com/entry/docker_intro)

# Docker-composeの構成
今回の構成は以下の前提を元に作られています。

- プロジェクトのマスターはHerokuにあり随時git pull/pushする
- データベースの中身はプレビュー用に必要なものだけ入っていればよく、データ構造が変わったときにだけ更新されるのでローカルにdumpを置きイメージ作成時にリストアされるようにする

### ディレクトリ構成
my_projectディレクトリを作成し、docker-compose.ymlとDockerfileをその直下に置きます。
またHerokuにあるステージングappのデータベースをエキスポートし、db/latest.dumpに置きました。
appディレクトリにはgit cloneしたRailsのプロジェクトデータ一式を置きます。

```
+ my_project
	- docker-compose.yml
	- Dockerfile
	+ db
		- latest.dump
	+ app // git cloneしたRailsプロジェクトデータ一式（Gemfile等含む）
```

### docker-composeファイルの中身

```yml:docker-compose.yml
version: '2'
services:
  db:
    image: postgres
    expose:
      - "5432"
    volumes:
      - psql-data:/db
      - ./db:/db
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ./my_app:/app  
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
    psql-data:
      driver: local
```
**Windows特有の問題**
Windowsだとdocker-composeのバージョンによってはvolumeのパスに`./my_app:/app`のような相対パスが使えません。dockerは元々LINUXベースのためWindowsスタイルのパスをうまく読み込めないらしいです。
対応策としては、最新のdocker for Windowsを使うか`\c\Users\hoge\`のような絶対パスで記述する、またはdocker toolboxを使う場合docker-compose1.9.0以上で環境変数`COMPOSE_CONVERT_WINDOWS_PATHS=1`に設定することで相対パスが使えるようになります。

参考：
[On native Windows, paths should not be "UNIXized"| docker/compose](https://github.com/docker/compose/issues/3923)
[Do not normalize volume paths on Windows by default | docker/compose](https://github.com/docker/compose/pull/4026)

### Dockerfileの中身

```Dockerfile
FROM ruby:2.3.1

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

RUN mkdir /app
ADD ./app /app
ADD ./db /db
WORKDIR /app
RUN bundle install
```

### database.ymlを変更
Docker上のPostgreSQLに接続するためにプロジェクトのdatabase.ymlを変更する必要があります。
developmentのhostをdbに、usernameをpostgresに変更します。

```yml:config/database.yml
development:
  <<: *default
  host: db
  username: postgres
```
今回はベタで書いてしまいましたが、ENV['postgresuser']みたいに環境変数で設定する方が状況によっては良いかも。


## docker-composeでイメージの作成とデータインポート

ファイル構成が全部できたらdocker-composeファイルに従ってdockerイメージをビルドします。
必要なファイル類のインストールがすべて行われるのでビルドには時間がかかりますのでしばらく放置。


```sh:
$ docker-compose build
```

### PostgreSQLのデータベース作成・マイグレーション・データリストア
データベースを作成し、マイグレーション。
Herokuのステージングappのdumpデータをインポートします。

```sh:
# DB作成とマイグレーション
$ docker-compose run web bundle exec rake db:create
$ docker-compose run web bundle exec rake db:migrate

# DBのコンテナ名を調べる
$ DOCKER_DB_NAME=`docker-compose ps -q DB_CONTAINER_NAME`

# Heroku appのdumpデータをリストア
$ docker exec -i $DOCKER_DB_NAME pg_restore --verbose --clean --no-acl --no-owner -U PG_USERNAME -d DB_NAME < PATH_TO_DUMPFILE
```
HerokuからダウンロードしたPostgreSQLのデータをリストアする方法を探すのにすごく苦労しました。
参考先のサイトのページの管理者様に感謝。

参考：[pg_restore a local db dump into Docker](https://gist.github.com/jgillman/8191d6f587ffc7207a88e987e034b675)

**Windows特有の問題**
2016年12月現在のWindows版docker-composeだと`docker-compose run`コマンドが使えないようです。
docker-compose1.9.0からは使えるようになっているとのことだったので1.9.0RC版を導入してみましたが問題なく使えました。

参考：[windows環境でのdocker-composeのInteractive Modeが実行出来ないのが解決した | Qiita](http://qiita.com/fagai/items/54b82b85dc02fe7f48f7)



# メンバー側の準備
## 1. Dockerのインストール
**Docker for Mac** https://docs.docker.com/docker-for-mac/

**Docker for Windows** https://docs.docker.com/docker-for-windows/

Stable Channelの項目の下にある **Get Docker for MacまたはWindows(stable)** ボタンを押してアプリをダウンロード、インストールします。


WindowsのOSの種類によってはDocker for Windowsが使えないことがあります。
2016年12月時点ではWindows10 Homeはダメでした。
Macでもダメなことがあるのかな？わかりません。
ダメだった場合はDocker Toolboxをダウンロードします。
**Docker Toolbox**　
https://www.docker.com/products/docker-toolbox
Mac/Win該当のOSのマークのボタンを押すとgithubに飛ぶのでページ下部にあるリンクからファイルをダウンロードしインストールます。
Windowsなら.exe、Macなら.pkgです。


## 2. Herokuのappデータをローカルに落とす
※ Heroku上のプロジェクトをチームで作るのでなければこのステップは不要です。

### [1] Heroku toolbeltのインストール
以下のページのWindowsのところにあるWindows Installerをクリック/ダウンロードしてインストールします。
https://devcenter.heroku.com/articles/heroku-command-line

Heroku toolbeltのフルパッケージを選択することでgit関連のツールもまとめてインストールできます。



### [2] プロジェクトデータをclone
コマンドプロンプトでプロジェクトを作りたい場所に移動し、以下のコマンドでHeroku上のappデータをclone

```
$ heroku git:clone -a APP_NAME
```

※ Herokuのappオーナー側で事前にコラボレーターの追加を行う必要があります。
参考：[Collaborating with Other Developers on Your App | Heroku](https://devcenter.heroku.com/articles/collaborating)

### [3] Dockerのセッティング
dockerファイル一式をまとめたものを環境を作ってる人から受け取ります。このフォルダ名をmy_projectとします。
my_projectフォルダ内にHerokuから落としてきたソースファイルのフォルダを移動してappという名前に変更します。
フォルダ構成は以下のようになります。

```
+ my_project
	+ db
	+ app
	- docker-compose.yml
	- Dockerfile
```

#### 環境変数の設定
Windows10なら左下の検索窓で「環境変数」と入力すれば環境変数の設定ウインドウが開きます。
ユーザー環境変数の「新規」で以下の２つを設定します。
①変数：COMPOSE_CONVERT_WINDOWS_PATHS　値：1
②変数：MY_PROJECT_HOST　値：http://192.168.99.100:3000

※MY_PROJECT_HOSTはrails内でasset_hostの設定に使います。

#### Docker Quickstart Terminalでコマンド入力して初期設定
Docker Toolboxをインストールした際に **Docker Quick Start Terminal**というアプリが入ったと思います。
Docker Quick Start Terminalを起動し、以下のコマンドを一行ずつ順番に入れて実行します。

```
$ cd docker-compose.ymlのフォルダパス
$ docker-compose build
$ docker-compose up -d
$ docker-compose run web rake db:create
$ docker-compose run web rake db:migrate
$ DOCKER_DB_NAME=`docker-compose ps -q db`
$ docker exec -i $DOCKER_DB_NAME pg_restore --verbose --clean --no-acl --no-owner -U postgres -d kodomoto_dev < ./db/latest.dump
```

準備はここまでで終了です。

※ほんとは上のコマンドをデザイナーさんに全部やってもらうのは微妙なのでバッチファイルにしたかったのですがうまくできませんでした。わかる方いたらぜひ教えてください。

## アプリの起動と終了
長くなったので別記事に分けました。
[Docker-composeの起動と終了(Windows)](http://qiita.com/tomomomo1217/items/e648b0a376330c55fbd3)

# 番外編:Postgresqlのローカルホストに接続する（検討してやめた）
Herokuのステージングappのpostgresのデータをローカルにインポートしたかったので、PostgreSQLをDocker化せずRailsコンテナからlocalhostに接続するという方法も検討しました。
この方法にする利点としては`dropdb`と`heroku pg:pull`の二つのコマンドだけでステージング環境からデータベースのインポートができるので更新があった場合にも簡便だということがあります。
しかし調べてみたら設定周りでとてもデザイナーさんにやってもらうのには面倒そうなものがあったのでやめました……。

参考：[Allow docker container to connect to a local/host postgres database | stack overflow](http://stackoverflow.com/questions/31249112/allow-docker-container-to-connect-to-a-local-host-postgres-database)

# 参考
[Container Registry and Runtime | Heroku](https://devcenter.heroku.com/articles/container-registry-and-runtime)
[Docker-compose.yml: from V1 to V2](https://medium.com/@giorgioto/docker-compose-yml-from-v1-to-v2-3c0f8bb7a48e#.khe2nwjwl)
[docker-compose で Rails の開発環境を作る](http://qiita.com/skyriser/items/2cf98b747ed6577cc5ee)
[DockerToolboxで作るWindows用開発環境の構築](http://qiita.com/stbmp23/items/ea23f32d04882c2c46d9)