本記事では、DBを使うアプリをGigalixirにデプロイする方法を解説します。
@piacerex さんの記事の以下節の作業が終わっていることを前提とします。
-
【本番構築Gigalixir編①】Elixir/Phoenixの初期PJリリースまでの手順
- Gigalixirのアカウント作成
- PJフォルダをGigalixirリモートレポジトリに設定
-
【本番構築Gigalixir編②】Elixir/Phoenixで構築したCRUD Webアプリをリリース
- gigalixirコマンドのインストール
- ssh公開鍵の設定
作業環境
リモートのGigalixirはFree Planを使用します。
Elixirのversionは1.9.1です。
Phoenixのversionは1.4.11です。
アプリケーションは作成済のチャットアプリです。
アウトライン
以下の順に解説します。
- DBを作成する
Gigalixirにデプロイしたアプリケーションが接続するDBを作成します - Phoenixの本番(Production)環境設定をする
DBへの接続の設定、Endpointの設定を行います - デプロイする
アプリケーションをGigalixirにデプロイします - DBの初期準備をする
migrationを行います。また必要に応じて種データを準備します
DBを作成する
gigalixirコマンドでアプリケーションが接続するDBを作成します。
# 作成
$ gigalixir pg:create --free
# 確認
$ gigalixir pg # 以下でブランクとした部分に値が表示されます。
[
{
"app_name": "",
"database": "",
"host": "",
"id": "",
"limited_at": null,
"password": "",
"port": 5432,
"state": "AVAILABLE",
"tier": "FREE",
"url": "",
"username": ""
}
]
参考:How to provision a Free PostgreSQL database
Phoenixの本番(Production)環境設定をする
Production環境の設定はprod.exs, prod.secret.exsに行います。
prod.secret.exsのフォーマットはPhoenix 1.4.4以降とそれ以前で違うため、設定方法が異なります。
今回は1.4.11なので1.4.4以降の設定方法を以下で紹介します。
※1.4.3以前の設定方法はConfiguration and Secretsを参照ください。
prod.secret.exs
ファイル名のとおりProduction環境固有の秘匿しておきたい情報を設定します。
例えば、DBへの接続情報である、URL、ユーザ名、パスワード、ポート等はそれにあたります。
そういった情報を設定ファイルに直書きせず、デプロイ先の環境変数から読み込みます。
デプロイ先の環境変数の設定方法は後述します。
編集はsslのコメントアウトを外すのみです。
use Mix.Config
database_url =
System.get_env("DATABASE_URL") ||
raise """
environment variable DATABASE_URL is missing.
For example: ecto://USER:PASS@HOST/DATABASE
"""
config :tombo_chat, TomboChat.Repo,
ssl: true, # ←ココ!!
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
secret_key_base =
System.get_env("SECRET_KEY_BASE") ||
raise """
environment variable SECRET_KEY_BASE is missing.
You can generate one by calling: mix phx.gen.secret
"""
config :tombo_chat, TomboChatWeb.Endpoint,
http: [:inet6, port: String.to_integer(System.get_env("PORT") || "4000")],
secret_key_base: secret_key_base
prod.exs
編集はhostとportを以下に変更し、schemeを追加します。
host: "[your-app-name].gigalixir.com"
port: 443
scheme: "https"
config :tombo_chat, TomboChatWeb.Endpoint,
url: [scheme: "https", host: "your-app-name.gigalixirapp.com", port: 443], # ココ
cache_static_manifest: "priv/static/cache_manifest.json"
# Do not print debug messages in production
config :logger, level: :info
# 中略
import_config "prod.secret.exs"
※prod.secret.exsはprod.exsから読み込まれることが分かります。
※urlはTomboChatWeb.Router.Helpersを使ってurlを生成する際に使用されます。例えば、
TomboChatWeb.Router.Helpers.static_url(TomboChatWeb.Endpoint, "/")は上記設定により
"https://your-app-name.gigalixir.com/" を返すようになります。"
[your-app-name]はgigalixirコマンドで確認できます。
$ gigalixir apps
[
{
"cloud": "gcp",
"region": "v2018-us-central1",
"replicas": 1,
"size": 0.3,
"stack": "gigalixir-18",
"unique_name": "your-app-name" # ココ
}
]
デプロイする
PhoenixのProduction環境用の設定ができたのでデプロイ作業を行います。
デプロイ先の環境変数の確認と設定
prod.secret.exsはDATABASE_URL、POOL_SIZE、SECRET_KEY_BASE、PORTの4つの環境変数の読み込みを行います。
このなかで設定が必須なのはDATABASE_URLとPOOL_SIZEです。
# 現在の環境変数の確認
$ gigalixir config
{
"DATABASE_URL": ""
}
# 設定:gigalixir config:set KEY_NAME=VALUE
$ gigalixir config:set DATABASE_URL="" # ""をgigalixir pgで表示される情報の"url"の右辺値とします。
$ gigalixir config:set POOL_SIZE=2 # Free PlanではPOOL_SIZEを2とする必要があります。
Elixir, Erlang, Node, NPMのversion指定
Gigalixirでアプリケーションを動作させる際のElixir, Erlang, Node, npmのバージョンを指定します。
参考:Specify Versions
Phoenixアプリケーションのルートディレクトリの直下にelixir_buildpack.configを作成し、バージョンを指定します。
例えば以下です。自身の開発環境に合わせてください。
# Erlang version
erlang_version=22.2
# Elixir version
elixir_version=1.10.0
# We can set the version of Node to use for the app here
node_version=12.14.0
# We can set the version of NPM to use for the app here
npm_version=6.13.7
※デプロイに必要なファイルのためgit管理下に忘れずに入れてください。ファイル名を間違えると正しく動作しません。
※NPMの6.13.4〜6.13.6はバグがありデプロイできなかったので注意
デプロイ
git pushでgigalixirにデプロイします。
git remoteへの追加はPJフォルダをGigalixirリモートレポジトリに設定を参照ください。
$ git push gigalixir master
# ローカルブランチをリモートマスターに送る場合は以下
$ git push gigalixir local_branch:master
動作確認
gigalixirコマンドでステータスを見たり、ログを見たりできます。
ステータスを見る
$ gigalixir ps
{
"cloud": "gcp",
"pods": [
{
"lastState": {},
"name": "",
"status": "Healthy",
"version": "1"
}
],
"region": "v2018-us-central1",
"replicas_desired": 1,
"replicas_running": 1,
"size": 0.3,
"stack": "gigalixir-18",
"unique_name": ""
}
ログを見る
$ gigalixir logs
DBの初期準備をする
デプロイができ、データベースとの接続ができたので、
データベースの初期準備としてmigrationと種データの用意をします。
migration
gigalixirコマンドでmigrationをします。
$ gigalixir run mix ecto.migrate
種データの用意
Gigalixirのiexに入って、スクリプトを実行します。
今回はbackend_seeds.exsという種データをDBに挿入するスクリプトを予め用意したので、それを実行します。
$ gigalixir ps:remote_console
iex> pwd
/app
iex> ls
.bash_history .basher .bashrc
.cache .formatter.exs .gitignore
.heroku .hex .mix
.platform_tools .profile .profile.d
.release Procfile README.md
_build app.tar.gz assets
config deps elixir_buildpack.config
lib mix.exs mix.lock
priv test
iex> cd "priv/repo"
iex> ls
backend_seeds.exs migrations seeds.exs
iex> c "backend_seeds.exs"
トラブルシュート
remote: npm ERR! invalid bin entry for package
NPMのバグです。NPMのversion指定を見直してください。
remote: cp: cannot overwrite directory ‘/tmp/cache/node_modules/phoenix’ with non-directory
gigalixirのbuild cashが残っているためのようです。
以下で解消されます。
$ git -c http.extraheader="GIGALIXIR-CLEAN: true" push gigalixir master
参照:How to clean your build cache
おわり
DBを使うPhoenixアプリケーションをGigalixirにデプロイする方法を順に説明しました。
アプリケーション作成後のデプロイ練習の一手目にGigalixirを試せてよかったです。
**「いいね」**よろしくお願いします。