Edeliverを使ってElixirアプリケーションをデプロイする
Elixirアプリケーションのデプロイツールはedeliverが一番人気のようです。
edeliverはRubyのCapistranoのようなツールです。
今回はedeliverを使ってPhoenixアプリケーションをEC2のサーバにデプロイします。
edeliverの仕組み
edeliverはビルド専用のマシンでアプリケーションをビルドし、productionサーバにデプロイします。
内部ではDistilleryというリリースパッケージを作成するツールを利用しています。
デプロイフローを図にすると以下のようになります。
ビルドサーバには事前にErlang, Elixir, NodeJSをインストールする必要があります。
セットアップ
ssh-agentの設定
edeliverはversion管理にgitを使用します。
ビルドサーバでgitを使ってチェックアウトするためにssh-agentの設定が必要になります。
以下コマンドでssh−agentの設定を行います。
$ ssh-add -K 鍵のフルパスファイル名
依存ライブラリの追加
デプロイ対象のphoenixアプリケーションのmixファイルに追加します
defp deps do [ {:phoenix, "~> 1.3.0"}, {:phoenix_pubsub, "~> 1.0"}, {:phoenix_ecto, "~> 3.2"}, {:postgrex, ">= 0.0.0"}, {:phoenix_html, "~> 2.10"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, {:gettext, "~> 0.11"}, {:cowboy, "~> 1.0"}, {:edeliver, "~> 1.4.4"}, ## これ {:distillery, ">= 0.8.0", warn_missing: false} ## これも ] end
ダウンロードします。
$ mix do deps.get, compile
設定ファイルの追加
プロジェクトルートに.deliver/config
ファイルを追加します。
以下内容の設定を行います。
- ビルドサーバとリリース対象サーバをそれぞれ設定する
- ホスト名
- ユーザー名
- ビルドディレクトリ
- リリースサーバのdeploy先ディレクトリ
- prod.secret.exsファイルのビルドサーバでの取得先を指定します
- パスワードを設定するファイルなのでリポジトリには追加しないファイルです
- このファイルに後ほどsecret_key_baseとデータベース設定を記述します
ファイルは以下のようになります
(BUILD_HOST, PRODUCTION_HOSTに指定したサーバは ~/.ssh/config
にも設定を追加します)
# .deliver/config APP="deploy_test_app" BUILD_HOST="build-server" BUILD_USER="ec2-user" BUILD_AT="/tmp/edeliver/deploy_test_app/builds" PRODUCTION_HOSTS="production-server" PRODUCTION_USER="ec2-user" DELIVER_TO="/home/ec2-user" # For *Phoenix* projects, symlink prod.secret.exs to our tmp source pre_erlang_get_and_update_deps() { local _prod_secret_path="/home/ec2-user/builds/config/prod.secret.exs" if [ "$TARGET_MIX_ENV" = "prod" ]; then __sync_remote " ln -sfn '$_prod_secret_path' '$BUILD_AT/config/prod.secret.exs' " fi } pre_erlang_clean_compile() { status "Installing NPM dependencies" __sync_remote " [ -f ~/.profile ] && source ~/.profile set -e cd '$BUILD_AT/assets' npm install $SILENCE " status "Building static files" __sync_remote " [ -f ~/.profile ] && source ~/.profile set -e cd '$BUILD_AT/assets' mkdir -p priv/static npm run deploy $SILENCE " status "Running phoenix.digest" __sync_remote " [ -f ~/.profile ] && source ~/.profile set -e cd '$BUILD_AT' APP='$APP' MIX_ENV='$TARGET_MIX_ENV' $MIX_CMD phoenix.digest $SILENCE " }
gitignoreに追加&コミット
ビルドサーバで作成したバイナリはローカルのディレクトリに保存されます。
(設定でS3に保存することもできます)
ディレクトリをgit管理の対象外にします。
$ echo ".deliver/releases/" >> .gitignore
そしてコミットします(コミットしないとデプロイできません)。
$ git commit -m "Setting up edeliver"
サーバPortの設定
config/prod.exs
ファイルにサーバのport番号を設定します。
(phoenixアプリケーションはデフォルトで4000番を使います)
config :deploy_test_app, DeployTestAppWeb.Endpoint, load_from_system_env: true, http: [port: 4000], url: [host: "example.com", port: 80], server: true, cache_static_manifest: "priv/static/cache_manifest.json"
DistilleryのSetup
edeliverが内部で使用しているdistilleryの初期化を行います。
$ mix release.init
rel/config.exsファイルが作成されます。
再度コミットしてからpushします。
$ git commit -m "Setting up distillery" $ git push origin master
secretファイルの編集
ビルドサーバにsshして prod.secret.exs
ファイルを作成しsecret_key_base, database情報を設定します。
保存場所は先ほど作成した .deliver/config
ファイルに記述している場所です。
設定項目は以下です。設定値はそれぞれアプリケーション固有の情報になります
use Mix.Config config :deploy_test_app, DeployTestAppWeb.Endpoint, secret_key_base: "yoursecretkeybasecomeshere" # Configure your database config :deploy_test_app, DeployTestApp.Repo, adapter: Ecto.Adapters.Postgres, username: "yourdatabaseusercomeshere", password: "yourdatabasepasswordcomeshere", database: "deploy_test_app_prod", hostname: "yourdatabasehostcomeshere", pool_size: 15
ビルド&デプロイ
ここまででデプロイのための設定は終わりです。
コマンドを自端末で実行しビルド、デプロイしましょう。
ビルド
それではビルドします。
次のコマンドを実行するとビルドサーバでビルドが行われます。
$ mix edleiver build release production
master以外のブランチを指定する場合は--branchオプションを追加します。
$ mix edeliver build release production --branch=$BRANCH_NAME
デプロイ
次のコマンドで設定したプロダクションサーバにデプロイします。
$ mix edeliver deploy release to production
更新
初回デプロイ以降は以下のコマンドで更新します。
$ mix edeliver upgrade
DB作成
最初のデプロイの場合、アプリケーションで使用するデータベースを作成する必要があります。
$ MIX_ENV=prod mix ecto.create
データベースを作成したらmigrationを実行します。
$ mix edeliver migrate production
アプリケーション起動
以下コマンドでアプリケーションを起動します。
$ mix edeliver start production
お疲れ様でした。これでデプロイの一連の作業は完了です。
その他
リリース先のサーバでアプリケーションを起動、停止するにはアプリケーションのルートディレクトリで以下のコマンドを実行します。
$ ./bin/deploy_test_app start
(停止するときはstop、再起動するときはrestartです)
replで起動することもできます。調査の時に便利です。
$ ./bin/deploy_test_app remote_console
参考情報
edeliver
Deploying Elixir applications with Edeliver
Deploy Early and Often: Deploying Phoenix with Edeliver and Distillery (Part Two)