de・ploy | dɪplɔ́ɪ |
他動詞
1 〘軍〙 〈部隊など〉を展開させる, 〈兵器など〉を配置[配備]する.
ウィズダム英和辞典
いまさらなのですが。
Phoenix のドキュメントに Docker container を利用したリリースの手順が追加されていることに気がつきました。 今夏のアップデートで追加されたようです。
また Heroku のドキュメントにも Docker container を利用したデプロイの手順が掲載されています。
従来から Phoenix アプリケーションを Heroku にデプロイするには buildpack を利用する手順がドキュメントに記載されていますが、これらのドキュメントに従えば Docker container を利用したリリースが可能になるはずです。
と、いうわけで。 Phoenix アプリケーションを new するところから Heroku にデプロイするまでの手順をまとめてみました。
いずれも Phoenix あるいは Heroku のドキュメントに記載されている内容ですので難しいことはないと思いますが、細かなところで情報が分散していてつまづくところがあったので何かの参考になればと思います。
{:elixir, "~> 1.9"}
なお Config
モジュールと mix release
コマンドを利用するので Elixir は 1.9 以上が必要です。
プロジェクトを用意する
プロジェクトを作成します。
$ mix phx.new hoge
$ cd hoge
Heroku はリポジトリの設定を .git/config
に記録するので、Git のリポジトリを作成しておいてください。
設定が記録できればよいのでコードの変更を commit しておく必要はないのですが、一般的に作業の巻き戻しなどに備えて適宜 commit しながら進めてください。
$ git init $ git add . $ git commit -m 'initial commit'
Config を変更する
config ファイルを書き換えます。
書き換えについては Phoenix のドキュメント「Deploying with Releases」のセクション「Runtime configuration」に解説があります。
ファイル名の変更
ディレクトリ config/
にある prod.secret.exs
のファイル名を releases.exs
に変更します。
releases.exs の編集
releases.exs
の内容を編集します。
まず、モジュール Config
を利用するように変更します。
use Mix.Config
を import Config
に書き換えます。
--- a/config/prod.secret.exs +++ b/config/releases.exs @@ -2,7 +2,7 @@ # from environment variables. You can also hardcode secrets, # although such is generally not recommended and you have to # remember to add this file to your .gitignore. -use Mix.Config +import Config
次に Endpoint の設定に server: true
を追加します。
--- a/config/prod.secret.exs +++ b/config/releases.exs @@ -25,7 +25,8 @@ secret_key_base = config :hoge, HogeWeb.Endpoint, http: [:inet6, port: String.to_integer(System.get_env("PORT") || "4000")], - secret_key_base: secret_key_base + secret_key_base: secret_key_base, + server: true
これは Mix を利用せずに単独でサーバとして起動するための設定です。
:server
- whentrue
, starts the web server when the endpoint supervision tree starts. Defaults tofalse
. Themix phx.server
task automatically sets this to true
なお Heroku の制限として、HTTP のポートは Heroku が設定する環境変数 PORT
の値を利用する必要があります。
- The web process must listen for HTTP traffic on
$PORT
, which is set by Heroku.Dockerfile commands and runtime / Container Registry & Runtime (Docker Deploys) | Heroku Dev Center
ただこれは自動生成される config に port: String.to_integer(System.get_env("PORT") || "4000")
と最初から設定されていますので変更せずこのままで大丈夫です。
また config/releases.exs
については、一つ前の記事に簡単にまとめましたので参考にしてみてください。
不要な設定の削除
prod.secret.exs
が不要になったので prod.exs
内の prod.secret.exs
を読み込んでいる行を削除します。
--- a/config/prod.exs +++ b/config/prod.exs @@ -52,4 +52,3 @@ config :logger, level: :info # Finally import the config/prod.secret.exs which loads secrets # and configuration from environment variables. -import_config "prod.secret.exs"
Dockerfile を用意する
Dockerfile を用意します。 アプリケーション名が現れるのはリリース版のファイルをコピーする部分とサーバを起動する部分のみです。 この二つを書き換えるだけで他のプロジェクトでも基本的に同じ内容で対応できます。
######################################## # ビルド ######################################## FROM elixir:1.9-alpine as build WORKDIR /app # ビルドに必要なツールをインストールする RUN apk add --update git build-base nodejs yarn npm # Hex と rebar をインストールする RUN mix local.hex --force && mix local.rebar # ビルド時の環境変数を設定する ENV MIX_ENV=prod # 依存するパッケージをインストールする COPY mix.exs ./ COPY mix.lock ./ COPY config ./config RUN mix deps.get --only prod RUN mix deps.compile # assets をインストールする COPY assets ./assets RUN npm install --prefix ./assets && npm run deploy --prefix ./assets RUN mix phx.digest # ビルドする COPY priv ./priv COPY lib ./lib RUN mix compile # リリース版を構築する # リリースの設定を rel/ に用意しているばあいは、それのコピーもしておいてください # COPY rel ./rel RUN mix release ######################################## # リリースするイメージを構築する ######################################## FROM alpine:3.10 as web WORKDIR /app # 実行時に必要なツールをインストールする RUN apk add --update bash openssl # ビルドしたリリース版のファイルをコピーする # アプリケーション名の部分 ( `hoge` ) は作成したアプリケーションの名前に合わせてください COPY --from=build /app/_build/prod/rel/hoge ./ # ユーザを設定する RUN chown -R nobody: /app USER nobody # 実行時の環境変数を設定する ENV HOME=/app # サーバを起動する # アプリケーション名の部分 ( `hoge` ) は作成したアプリケーションの名前に合わせてください CMD bin/hoge start
Heroku にデプロイする
Heroku アプリケーションの作成
まず Heroku のコンテナリポジトリにログインします。
$ heroku container:login
次に Heroku に新しいアプリケーションを作成します。
heroku create
コマンドを使って、あるいは Heroku のコンソールを利用して作成します。
$ heroku create hoge-with-docker
環境変数の設定
環境変数を設定します。
SECRET_KEY_BASE
を設定します。
ここでは mix phx.gen.secret
コマンドで生成した値を設定しています。
heroku config:set
コマンドを使って、あるいは Heroku のコンソールを利用して設定します。
$ heroku config:set SECRET_KEY_BASE=`mix phx.gen.secret`
データベースの設定
データベースを利用するばあい、データベースの設定をします。
Heroku のアドオンを利用するばあい、heroku addons:create
コマンドを使って、あるいは Hroku コンソールを利用して設定します。
$ heroku addons:create heroku-postgresql
アドオンを利用したばあいは接続先の URL が環境変数の DATABASE_URL
に設定されます。
config/releases.exs
の初期状態では DATABASE_URL
から接続先の情報を取得するようになっているので、この状態でデプロイすればデータベースに接続できるようになります。
Heroku のアドオン以外のデータベースを利用するばあいは、そのデータベースのURLを DATABASE_URL
に設定してください。
$ heroku config:set DATABASE_URL=postgres://USER:PASSWORD@DOMAIN:PORT/DATABASE
Push the image and release
Docker イメージをビルドして Heroku に push します。
$ heroku container:push web
push したイメージをリリースします。
$ heroku container:release web
すべての準備が整ったので、デプロイしたアプリケーションを開きます。
ブラウザでアプリケーションの URL を入力して開くか、あるいは heroku open
コマンドでページを開きます。
$ heroku open
データベースのマイグレーション
データベースを利用するばあい、データベースのマイグレーションを実行する必要があります。
通常は mix ecto.migrate
コマンドを利用しますがリリース版は Mix を含まないためこのコマンドを実行できません。
このようなばあい、自分でマイグレーションの処理を用意し実行する必要があります。
これについても Phoenix のドキュメントに記載されています。
lib/hoge/
にマイグレーションを実行する関数を記述した次のような内容のファイル release.ex
を追加します。
ファイル名、ファイルの格納ディレクトリは、マイグレーションを実行できれば任意でかまわないのですが、ここではドキュメントに合わせた構成にしています。
# lib/hoge/release.ex defmodule Hoge.Release do @app :hoge def migrate do for repo <- repos() do {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true)) end end def rollback(repo, version) do {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version)) end defp repos do Application.load(@app) Application.fetch_env!(@app, :ecto_repos) end end
これをアプリケーションの eval コマンドで実行します。
Phoenix のドキュメントでは次のような実行例が記載されています。
$ _build/prod/rel/my_app/bin/my_app eval "MyApp.Release.migrate"
今回は Heroku にデプロイしているので Heroku 上でプロセスを実行するので heroku run
コマンドを利用します。
またリリースは _build/prod/rel/hoge/
以下の内容をデプロイしているので実行パスも bin/
以降を指定すればよく bin/hoge eval
という形になります。
全体として。次のようにマイグレーションを実行します。
アプリケーション名の部分 ( hoge
) 、モジュール名の部分 ( Hoge
) は作成されるアプリケーション、モジュールに置き換えて実行してください。
$ heroku run 'bin/hoge eval "Hoge.Release.migrate()"'
WebSocket を利用する
Phoenix.Channel や Phoenix.LiveView などで WebSocket を利用するばあい、 :check_origin
を設定する必要があります。
:check_origin
- configure transports to checkorigin
header or not. May befalse
,true
, a list of hosts that are allowed, or a function provided as MFA tuple. Hosts also support wildcards.
config/releases.exs に :check_origin
を追加します。
ここでは環境変数を利用した設定にしています。
# config/releases.exs config :hoge, HogeWeb.Endpoint, http: [:inet6, port: String.to_integer(System.get_env("PORT") || "4000")], secret_key_base: secret_key_base, check_origin: ["//#{System.get_env("HOST")}"], server: true
アプリケーションの環境変数に値を追加します。
$ heroku config:set HOST=hoge-with-docker.herokuapp.com
これで WebSocket のリクエストを受け付けることができるようになりました。
いつか読むはずっと読まない:古典
自分にとって長らくプログラミングスタイルの拠り所になっていたのは間違いなく「プログラム書法」でした。 さすがに現在ではそぐわない内容も多くなりましたが、プログラミングに対する姿勢はこの本で学びました。
「達人プログラマー」(翻訳旧版)を読んだとき、「現代の『プログラム書法』だ」と思ったものでした。
その「達人プログラマー」も現在ではすっかり古典となったようです。 古典であるからこそ、立ち返ってその考えをふたび吸収したいと思います。
- 作者: Brian W.Kernighan,P.J.Plauger,木村泉
- 出版社/メーカー: 共立出版
- 発売日: 1982/06/20
- メディア: 単行本
- 購入: 1人 クリック: 166回
- この商品を含むブログ (31件) を見る
- 作者: Andrew Hunt,David Thomas,村上雅章
- 出版社/メーカー: オーム社
- 発売日: 2016/10/20
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (8件) を見る