この記事はRailsチュートリアルの目次に沿って、PhoenixでWebアプリケーションを作ってみよう、という試みです。
(Phoenixは関数型プログラミング言語Elixirで記述されたWebフレームワークです。)
Railsチュートリアルではデプロイ環境としてherokuを使いますが、本記事ではElixir/Phoenix向けPassであるGigalixirを使います。
第1章 ゼロからデプロイまで
さっそく動かす
Phoenixのインストールガイドを見ながら進めていきます。
開発環境
Railsチュートリアルでは開発環境構築の複雑さを避けるためにAWS Cloud9(クラウドIDEサービス)を使っていますが、
以前Elixir実行環境を構築しているので、今回はローカルで進めます。
Elixirのインストール
以前Mac環境でElixirインストール、コードエディターVSCodeのインストール&設定をしました。
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
を表示します。やったね。
Hello, world!に書き換える
無事アプリが作成できたので、Welcome to Phoenix!をHello, world!に書き換えます。
書き換えるべきファイルはどこにあるんだ…?
Pdonenix Docsにディレクトリ構造の解説があるので、そちらからビューファイルを探していきましょう。
lib/hello_app_web/templates/layout/app.html.eex
とlib/hello_app_web/templates/page/index.html.eex
を編集するとよさそうですね。
よし、編集できたぞ!(ということにします)
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でプライベートリポジトリを作成します。
Githubにリポジトリが作成できました。
作成後の画面に表示されるコマンドを参考に、Githubリポジトリをリモートoriginに追加し、pushします。
$ git remote add origin git@github.com:<あなたのGitHubアカウント名>/hello_app.git
$ git push -u origin master
```
Githubに反映されてますね。よしよし。

### デプロイする
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 を使っているんだなあと気づきました。
(そうですよね?)