Phoenix のリリース用ビルド

# ポイント
* exrmを使ってビルドします。 ([公式のチュートリアル](http://www.phoenixframework.org/docs/advanced-deployment)参照)
* ビルド後に一式がパッケージ化された ```<app name>.tar.gz``` ができます。
* パッケージには erlang のランタイム環境も含まれています。
* （ランライム環境が含まれているので）ビルドはデプロイ環境と同じプラットフォームで行ってください。
    * mac でビルドして linux で実行は❌
* パッケージにランタイム環境が含まれているため、解凍して ```bin/<app> start``` を実行するだけでサーバーが起動できます。
* upgrade (hot deploy) は releases/<version> ディレクトリにtar.gz を置いて、```bin/<app> upgrade <ver>``` 。
   * ただし、ecto の create や migrate は実行されないため、別途行う必要があります。


# 手順
elixir / phoenix の勉強用に作成した[サンプル](https://github.com/yasuhiro-okada-aktsk/sample_phoenix_react) (tag 0.0.1と0.0.2)を使って説明します。

## ビルド用の設定
```mix.exs``` に exrmを追加します。

```ex:mix.exs
  defp deps do
    [{:phoenix, "~> 1.0.3"},
     {:phoenix_ecto, "~> 1.1"},
     {:mariaex, ">= 0.0.0"},
     {:phoenix_html, "~> 2.1"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:cowboy, "~> 1.0"},
     {:exrm, "~> 0.19.9"}]
  end
```

```config/prod.exs``` に ```server: true``` を追加します。(下記の例では port も固定にしています。)

```ex:config/prod.exs
config :sample_phoenix_react, SamplePhoenixReactApp.Endpoint,
  http: [port: 4001],
  cache_static_manifest: "priv/static/manifest.json",
  server: true
```

### ビルド
下記のような流れでビルドします。

```bash
export MIX_ENV=prod

npm install
mix clean
mix deps.get --only prod
mix compile

npm run gulpBuild
mix phoenix.digest

mix release
```

今回のサンプルでは ```gulp``` を使って web/static をビルドしていますが、```brunch``` を使う場合は、```npm run gulpBuild``` をbrunchに変更してください。

```mix phoenix.digest```は ```web/static``` のビルド後の ```priv/static``` 以下のファイルにdigestをつけ圧縮ファイルを作成します。

これが
<img width="672" alt="before-digest.png" src="https://qiita-image-store.s3.amazonaws.com/0/95713/383846cb-4e8c-9c7b-0452-23b0e2a13138.png">

こうなります。
<img width="671" alt="after-digest.png" src="https://qiita-image-store.s3.amazonaws.com/0/95713/d28e3201-42db-c762-a058-e5d7fbe538b6.png">

```mix release``` 後、```rel/<app>```ディレクトリ下に実行時のディレクトリのイメージができますが、デプロイに必要なのは```rel/<app>/releases/<version>/<app>.tar.gz```です。

## 新規リリース
※ ecto.create / migrate は実行されないため、あらかじめデータベースにテーブルを作成しておいてください。

```rel/<app>/releases/<version>/<app>.tar.gz``` を適当なディレクトリに展開します。

```bash
mkdir /server
cd /server
tar xvf ~/sample_phoenix_react.tar.gz
```

```bin/<app> start```を実行します。

```
bin/sample_phoenix_react start
```

## アップデート
実行環境の ```releases/``` ディレクトリに```<version>```ディレクトリを作成し、新しいバージョンの```rel/<app>/releases/<version>/<app>.tar.gz``` を置きます。 

```bash
cd /server/releases
mkdir 0.0.2
mv ~/sample_phoenix_react.tar.gz 0.0.2/
```

```bin/<app> upgrade <version>```を実行します。

```
bin/sample_phoenix_react upgrade 0.0.2
```

※ アップデート中にサーバーを停止する必要はありません。

# ecto の create / migrate

exrm 1.0.3 で `command`の機能が実装され、migrateも実行できるようです。（まだ動作確認していません。）

- (参考) [Running migration in an Exrm release « Plataformatec Blog](http://blog.plataformatec.com.br/2016/04/running-migration-in-an-exrm-release/)

~~現在のところ (phoenix 1.0.3)、```bin/``` にあるスクリプトでは ecto の create / migrate はできませんが、サーバーを起動できる場合、（少し強引ですが）rpc を使って ecto の create / migrate することもできます。~~

```bash:create
./bin/sample_phoenix_react rpc Elixir.Ecto.Storage up "['Elixir.SamplePhoenixReactApp.Repo']."
```

```bash:migrate
./bin/sample_phoenix_react rpc Elixir.Ecto.Migrator run "['Elixir.SamplePhoenixReactApp.Repo', <<\"/home/vagrant/server/lib/sample_phoenix_react-0.0.2/priv/repo/migrations\">>, up, [{all, true}]]."
```

# 参考
* [Exrm Releases · Phoenix](http://www.phoenixframework.org/docs/advanced-deployment)
* [How to run Ecto migrations from an exrm release](https://gist.github.com/antipax/90cc36d29c2a2a5d4629)
* [Running migration in an Exrm release « Plataformatec Blog](http://blog.plataformatec.com.br/2016/04/running-migration-in-an-exrm-release/)