PhoenixServerインストール(Ubuntu編)

# 概要
Elixir用のWebアプリケーションフレームワークであるPhoenixServerを
AWS EC2インスタンスに導入して、色々と勉強してみようと考えてみました。
しかし、想像以上にインストールだけで難しかったので、メモを記事に残しておこうと思います。
コツを掴めば、簡単なのですが、私の場合、色々な導入手順を参考にした結果、振り回されてしまったもので…
あと、バージョンが変わるとインストール手順も変わってくると思いますので、その点もご注意を。
なお、タイトルにUbuntu編と記載があるのはCentOS編もアップする予定であるためです。

## 手順サマリー
　1.AWSインスタンスの用意
　2.OSの基本設定/パッケージアップデートとサーバー再起動
　3.各種前提パッケージのインストール
　4.erlang/Elixirのインストール
　5.PostgreSQLの設定
　6.Elixirの初期設定/Phoenixサーバーの起動と設定
　7.セキュリティグループの設定を忘れずに

###1.AWSインスタンスの用意
使用したAMIは以下です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/e082e158-8162-6c30-d310-8d1e8899062f.png)

こちら、インスタンスタイプは```t2.micro```を指定しました。
用意ができたら、SSHで接続して、OSの基本設定に入ります。

###2.OSの基本設定/パッケージアップデートとサーバー再起動
以下の設定を行いました。

1.ホスト名の設定
2.AppArmorの無効化
3.sudoユーザーの作成(パスワード設定含む/rootも一緒に設定)

というわけで、上記に対して、実行したコマンドを記載していきます。

```bash:ホスト名の設定
hostnamectl set-hostname <MyHostName>
```

```bash:AppArmorの無効化
systemctl stop apparmor
systemctl disable apparmor
```

```bash:sudoユーザーの作成
useradd work01
passwd work01
```

```bash:ユーザーをsudoグループへ追加
gpasswd -a work01 sudo
```
※rootユーザーのパスワード変更手順は割愛しますね。

ここまで終了したら、ひとまず、パッケージを最新化して、再起動します。

```bash:パッケージの最新化/サーバー再起動
apt-get update -y
reboot
```

###3.各種前提パッケージのインストール
ここも個人的には結構なハマりポイントだと感じました。
Phoenixだけの話ではなく、前段となるerlangやElixirの導入時において、
パッケージを入れる順番、入れ方も複数の方法が存在するため、
私の場合、色々な手順を参考にして実施した結果、混乱しました（汗

なので、私の場合、この方法でうまくいったという手順をポイントともに記載しておきます。
※以降の手順は先ほど追加したwork01ユーザーで実施することを前提とします。

####3-1.aptitudeのインストール

```bash:aptitudeインストール
sudo apt-get install aptitude -y
```

####3-2.Phoenix用前提パッケージのインストール

```bash:前提パッケージのインストール1
sudo apt-get install build-essential libreadline-dev zlib1g-dev flex bison libxml2-dev libxslt-dev libssl-dev -y
```

```bash:前提パッケージのインストール2
sudo apt-get install inotify-tools -y
```

####3-3.PostgreSQLのインストール

```bash:PostgreSQLのインストール
sudo apt-get install postgresql postgresql-contrib -y
```

###4.erlang/Elixirのインストール

Phoenixの前提となるerlangとElixirをダウンロードするのですが、
apt-getで入手するためにリポジトリを追加しておく必要があります。

```bash:erlang用のリポジトリダウンロード
sudo wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb && sudo dpkg -i erlang-solutions_1.0_all.deb
```
リポジトリを追加したら、apt-getのアップデートを実行します。

```bash:apt-getのアップデート
sudo apt-get update
```
アップデートが完了したら、apt-getで```esl-erlang```を指定してインストールします。
注意なのは、アップデートする前にインストールを実行しても参照するリポジトリが古くて、
erlangがインストールされませんのでご注意を。

```bash:erlangのインストール
sudo apt-get install esl-erlang -y
```
erlangのインストールが終わったら、次にElixirをインストールします。

```bash:Elixirのインストール
sudo apt-get install elixir -y
```

ここで、Elixirのインストールが完了したことを確認するために以下のコマンドを実行します。

```bash:Elixirのバージョン確認
elixir -v
```

バージョンの情報が出力されればOKです。

###5.PostgreSQLの設定
次にPostgreSQLの設定を行います。
PostgreSQLのインストール時にデフォルトで用意される```postgres```ユーザーの
パスワードを以下で変更します。

```bash:postgresのパスワード変更
sudo -u postgres psql -c "ALTER USER postgres PASSWORD '<YourPassword>';"
```

理由は分からないのですが、気になったので、記載しておきますと、
私の場合、ここでパスワードをユーザー名と一致させると、
なぜか後ほど、ecto.createする際にエラーが発生しなくなりました…

```(例)"ALTER USER postgres PASSWORD 'postgres';"```

コマンド実行後にPostgreSQLサービスを再起動する。

```bash:PostgreSQLのサービス再起動
sudo service postgresql restart
```

```bash:PostgreSQLのサービス起動状態確認
sudo service postgresql status
```
サービスがStart状態になっていれば、OKです。

###6.Elixirの初期設定/Phoenixサーバーの起動と設定

Elixirが標準で搭載しているビルドツールmixを使用して、Phoenixを起動していきます。

```bash:Hexのインストール
sudo mix local.hex
```

Hexをインストールしたら、次にPhoenixをダウンロードし、ビルドします。

```bash:Phoenixのインストール
sudo mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez
```

Phoenixのプロジェクトを作成します。

```bash:Phoenixプロジェクト作成
sudo mix phx.new <YourProjectName>
```

プロジェクトを作成すると指定したプロジェクト名称のフォルダが作成されているので、
そのフォルダに移動して、タスクを実行します。
移動してからでないとタスクを実行できません。

```bash:ディレクトリの移動
cd <YourProjectName>/
```

以下のコマンドを実行することでデータベースを作成します。
こちらのコマンドの```ecto```とは```Phoenixがデータベースを操作する際のライブラリの名称```です。
私はRuby On RailsのActiveRecordに相当すると考えています。

ちなみにここが重要ポイントとなるのですが、以下のコマンドを実行する際は
```postgres```ユーザーに切り替わってから実行してください。

でないと皆さんご存知のPostgreSQLのアクセス制御に引っ掛かって、
ectoによるDB作成時にエラーが出力されて躓きます。

```bash:postgreユーザーへの切り替え
su postgres
```
環境変数まで切り替える必要はありませんでした。
(実行しているユーザーだけチェックされているからでしょうか？)

```bash:データベース作成
sudo mix ecto.create
```

ここまでできたら、Phoenixを起動させます。
と言いたいところなのですが、もう一つ罠が隠されています。
ちなみに起動する際のコマンドは```mix phx.server```です。

このまま起動させると以下のエラーが発生します。

```bash:エラー内容
** (Mix) Could not start application world: World.Application.start(:normal, []) returned an error: shutdown: failed to start child: WorldWeb.Endpoint
    ** (EXIT) shutdown: failed to start child: Phoenix.Endpoint.Handler
        ** (EXIT) "plug_cowboy dependency missing"
```

内容を確認してみると```** (EXIT) "plug_cowboy dependency missing"```
とありますので、これが原因だと思われますので、解消する必要があります。
内容としてはプラグの依存性に問題があるとのことですね。

プロジェクトのトップフォルダに```mix.exs```というファイルがありますので、こちらを編集します。

```bash:設定ファイルの編集
sudo cp -p <YourProjectName>/mix.exs <YourProjectName>/mix.exs.org
sudo vi <YourProjectName>/mix.exs
```
```vim:編集内容
 31   # Specifies your project dependencies.
 32   #
 33   # Type `mix help deps` for examples and options.
 34   defp deps do
 35     [
 36       {:phoenix, "~> 1.3.4"},
 37       {:phoenix_pubsub, "~> 1.0"},
 38       {:phoenix_ecto, "~> 3.2"},
 39       {:postgrex, ">= 0.0.0"},
 40       {:phoenix_html, "~> 2.10"},
 41       {:phoenix_live_reload, "~> 1.0", only: :dev},
 42       {:gettext, "~> 0.11"},
 43       {:cowboy, "~> 1.0"},
 新規追加  {:plug_cowboy, "~> 1.0"}
 44     ]
 45   end
```

ファイルの編集が終わったら、改めてこの状態でのライブラリの読み込みを実施します。
Railsのbundleインストールみたいな感じでしょうか。

```bash:deps.getコマンド
sudo mix deps.get
```
コマンドを実行し、最終的に以下の内容が出力されればOKです。

```bash:実行結果
New:
  plug_cowboy 1.0.0
* Getting plug_cowboy (Hex package)
```

あとはどうせ起動すると怒られますので、先にアセットをダウンロードしておきます。
アセットもプロジェクトのフォルダ配下にフォルダとして存在しています。
アセットは詳しく分からないですが、Elixir内のリソース定義を示すようです。

で、ちなみにここでnode.jsをインストールします。
というのも、やはり、なぜかは分かりませんが、先にnode.jsをインストールした状態で
ここまで、Phoenixサーバーのインストールを進めると、
npmコマンドが上手く起動しなくなる問題が発生するためです。

ですので、もうあまりここは深く考えずに、このタイミングでnode.jsとnpmコマンドを追加します。

```bash:node.jsインストール
sudo aptitude install nodejs -y
```

```bash:npmインストール
sudo apt-get install npm -y
```

```bash:アセットのダウンロード
cd assets && npm install
```
これで改めて、Phoenixサーバーを起動すれば動きます。

```bash:Phoenixの起動
sudo mix phx.server
```

###7.セキュリティグループの設定を忘れずに
ポートはデフォルトだと4000番で起動しますので、TCPの4000番を開けておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/b03701ca-0b66-3218-de40-fad46981b765.png)

これでアクセスしてみると、Welcomeページが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138274/a5b8bc92-46d7-a695-77cf-468f1b256e2e.png)