Railsチュートリアルの内容をPhoenixでやってみよう〜第1章 ゼロからデプロイまで

この記事は[Railsチュートリアル](https://railstutorial.jp/chapters/beginning?version=6.0#cha-beginning)の目次に沿って、PhoenixでWebアプリケーションを作ってみよう、という試みです。
（Phoenixは関数型プログラミング言語Elixirで記述されたWebフレームワークです。）

Railsチュートリアルではデプロイ環境としてherokuを使いますが、本記事ではElixir/Phoenix向けPassであるGigalixirを使います。

## 第1章 ゼロからデプロイまで

### さっそく動かす

Phoenixのインストールガイドを見ながら進めていきます。

https://hexdocs.pm/phoenix/installation.html

#### 開発環境

Railsチュートリアルでは開発環境構築の複雑さを避けるためにAWS Cloud9（クラウドIDEサービス）を使っていますが、
以前Elixir実行環境を構築しているので、今回はローカルで進めます。

#### Elixirのインストール

以前Mac環境でElixirインストール、コードエディターVSCodeのインストール＆設定をしました。

https://qiita.com/kn339264/items/86f2cd54c015b5ed49a0

#### Hexをインストールする

パッケージマネージャのHexをインストールします。

```
mix local.hex
```

#### Phonenixをインストールする

Elixirが1.6以降、Erlangが20以降であることを念の為確認します。

```
$ elixir -v
Erlang/OTP 24 [erts-12.0.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]

Elixir 1.12.2 (compiled with Erlang/OTP 24)
```

Phonenixをインストールします。（1.5.9は2021/7/27時点で最新バージョン）

```
$ mix archive.install hex phx_new 1.5.9
```

インストールしたPhoenixのバージョンを確認。

```
$ mix phx.new -v
Phoenix v1.5.9
```

### 最初のアプリケーション

#### Phoenixアプリの作成 

Hello, world!を表示するアプリケーションを作ります。
今回はDBを使わないので`--no-ecto`オプションを指定してみました。

途中で依存関係のインストールをするか尋ねられるのでYを入力します。

```
$ mix phx.new hello_app --no-ecto
* creating hello_app/config/config.exs
* creating hello_app/config/dev.exs
* creating hello_app/config/prod.exs
（中略）
Fetch and install dependencies? [Yn] Y
* running mix deps.get
* running mix deps.compile
```

Phoenixアプリ作成が終わると、次のようなメッセージが表示されます。

```
We are almost there! The following steps are missing:

    $ cd hello_app

Start your Phoenix app with:

    $ mix phx.server

You can also run your app inside IEx (Interactive Elixir) as:

    $ iex -S mix phx.server
```

では、Phoenixアプリを起動します。

```
$ cd hello_app
$ mix phx.server
Compiling 13 files (.ex)
Generated hello_app app
[info] Running HelloAppWeb.Endpoint with cowboy 2.9.0 at 0.0.0.0:4000 (http)
[info] Access HelloAppWeb.Endpoint at http://localhost:4000
```
`http://localhost:4000`を表示します。やったね。

![スクリーンショット 2021-08-04 23.56.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109744/b8193782-475e-aa9f-c0b2-4414e5d1bc91.png)

#### Hello, world!に書き換える

無事アプリが作成できたので、Welcome to Phoenix!をHello, world!に書き換えます。
書き換えるべきファイルはどこにあるんだ…？
Pdonenix Docsにディレクトリ構造の解説があるので、そちらからビューファイルを探していきましょう。

https://hexdocs.pm/phoenix/directory_structure.html#content

https://zenn.dev/koga1020/books/phoenix-guide-ja-1-5/viewer/directory_structure

`lib/hello_app_web/templates/layout/app.html.eex`と`lib/hello_app_web/templates/page/index.html.eex`を編集するとよさそうですね。

![スクリーンショット 2021-08-06 0.14.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109744/4c02cfb1-9fbc-657b-b6ef-00ed3b296ae2.png)

よし、編集できたぞ！（ということにします）

### Gitによるバージョン管理

Phoenixアプリのディレクトリに移動し、空のGitリポジトリを作成します。

```
$ cd hello_app/
$ git init
Initialized empty Git repository in /user/to/path/hello_app/.git/
```

作成したアプリのファイルをインデックスに追加、変更したファイルをリポジトリに反映します。

```
$ git add -A
$ git commit -m "Initialize repository"
```

githubでプライベートリポジトリを作成します。

![スクリーンショット 2021-08-06 0.25.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109744/833fadb3-a594-23c1-fc89-da81126c6b07.png)

Githubにリポジトリが作成できました。

![スクリーンショット 2021-07-29 1.21.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109744/853a97a3-8409-54ec-fcf1-42b1c113a6b9.png)

作成後の画面に表示されるコマンドを参考に、Githubリポジトリをリモートoriginに追加し、pushします。

````
$ git remote add origin git@github.com:<あなたのGitHubアカウント名>/hello_app.git
$ git push -u origin master
```

Githubに反映されてますね。よしよし。

![スクリーンショット 2021-08-06 0.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109744/1680c971-5458-67aa-fd20-f0e0b2300ff5.png)

### デプロイする

Elixir/PhoenixをサポートしているPaaSのGigalixirを使います。
Herokuを使ってもいいのですが、公式サポート言語ではないので、Herokuアプリ作成時に言語を自動判定できないのと、HerokuにPhoenix用buildpackの追加が必要になるようです。

くわしくは下記リンク先を参照ください。

https://hexdocs.pm/phoenix/heroku.html

#### Gigalixrを使おう

下記を参考に進めていきます。

https://hexdocs.pm/phoenix/gigalixir.html#content

https://zenn.dev/koga1020/books/phoenix-guide-ja-1-5/viewer/gigalixir


##### Gigalixir CLIのインストール

macOS、Linux、Windowsでインストール方法が異なります。環境に合わせてインストールしましょう。

https://gigalixir.readthedocs.io/en/latest/getting-started-guide.html#install-the-command-line-interface

私はmacOS環境なのでhomebrewでインストールします。

```
$ brew tap gigalixir/brew && brew install gigalixir
```

##### Gigalixirアプリの作成、セットアップ

Gigalixirにサインアップします。

```
$ gigalixir signup
```

翻訳より引用。Gigalixirを使う上で留意したい。

> Gigalixirのフリープランはクレジットカードは必要ではなく、無料で1つのアプリインスタンスと1つのpostgresqlデータベースを使うことができます。しかし、本番運用するつもりなら有料プランにアップグレードすることを検討してください。

Gigalixirにログインします。

```
$ gigalixir login
```

ログインしているアカウント情報が確認できます。

```
$ gigalixir account
```

Gigalixirアプリを作成します。

```
$ gigalixir create
```

作成したGigalixirアプリと、git remoteが追加されたことを確認します。

```
$ gigalixir apps
$ git remote -v
```

##### バージョン指定

Elixir、Erlang、Node.jsのバージョンがGigalixirのデフォルトのビルドパックだと古いので、開発環境とバージョンを合わせる。
作成したファイルはコミットしておく。

```
$ echo "elixir_version=1.12.2" > elixir_buildpack.config
$ echo "erlang_version=24.0" >> elixir_buildpack.config
$ echo "node_version=12.16.1" > phoenix_static_buildpack.config

$ git add elixir_buildpack.config phoenix_static_buildpack.config
$ git commit -m "set elixir, erlang, and node version"
$ git push origin master
```

指定するバージョンは下記コマンドで確認しています。

```
$ elixir --version
Erlang/OTP 24 [erts-12.0.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]

Elixir 1.12.2 (compiled with Erlang/OTP 24)
$ node -v
v12.16.1
```

##### デプロイ！！！！！

```
$ git push gigalixir master
```

アプリのステータスが`Healthy`になるまで待ちましょう。

```
$ gigalixir ps
```

Gigalixirで稼働しているアプリを表示します。

```
$ gigalixir open
```

表示できたら終わりです、ッシャー！

## おわりに

今回はDBを使わないのでPhoenixアプリ作成や、Gigalixirアプリ作成のDB設定を飛ばしています。

別言語でRailsチュートリアルをすることで、Webアプリケーション開発する上で必要な点をすべて押さえているなあとRailsチュートリアルの内容の凄さを再確認しました。
Ruby on Rails以外に、コマンドラインで使うUnixコマンドの解説、Gitの解説、必要な要素をすべて解説しているという、Railsチュートリアルのストロングさ。。これが無料で読めるのか。。

また、Phoenix公式の英文を読むのがつらい時に @koga1020 さんの日本語訳にとても助けられました。次もお世話になります。
https://zenn.dev/koga1020/books/phoenix-guide-ja-1-5

### 追記

```
$ echo "erlang_version=24.0" >> elixir_buildpack.config
```

と記載するところを

```
$ echo "erlang_version=24" >> elixir_buildpack.config
```
と書いたところ、Gigalixirへのデプロイ途中でエラーになりました。

```
$ git push gigalixir master
-----> Checking Erlang and Elixir versions
       Will use the following versions:
       * Stack heroku-20
       * Erlang 24
       * Elixir v1.12.2
       Sorry, Erlang 24 isn't supported yet. For a list of supported versions, please see https://github.com/HashNuke/heroku-buildpack-elixir#version-support
remote: 2021/08/05 16:43:04 exit status 1
remote: Deploy aborted
To https://git.gigalixir.com/xxxx-xxxx-xxxx.git/
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.gigalixir.com/xxxx-xxxx-xxxx.git/'
```

このエラーが出たタイミングで、GigalixirもElixirのbuildpackに https://github.com/HashNuke/heroku-buildpack-elixir を使っているんだなあと気づきました。
（そうですよね？）