phoenix-ops について
Elixir/Phoenix 開発者向けの本番運用ガイドです。リリース、ランタイム設定、クラスタリング、可観測性、セキュリティ対策に加え、バックグラウンドジョブやヘルスチェック、デプロイ方法も扱います。
主な機能
- 01本番リリースとランタイム設定
- 02クラスタリング、PubSub、Presence の設計
- 03テレメトリー、ログ、メトリクスの設定
- 04HTTP エンドポイントとネットワークの強化
- 05バックグラウンドジョブとデプロイ方法
活用シーン
- 01Phoenix アプリの本番リリース準備
- 02ノード間の Presence 不整合の調査
- 03サービスへのメトリクスとヘルスチェック追加
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ bobmatnyc/ claude-mpm-skills --skill phoenix-opsインストール後、Claude Code で/phoenix-opsを入力して読み込まれたか確認します。
同梱ファイルmetadata.json
詳細
Phoenix の運用とデプロイ(Elixir/BEAM)
本番環境に対応した Phoenix アプリでは、リリース、ランタイム設定、テレメトリ、クラスタリング、セキュアなエンドポイントが重要です。適切に設定すれば、BEAM によってローリング再起動と監督による高い回復性を実現できます。
リリースとランタイム設定
MIX_ENV=prod PHX_SERVER=true mix assets.deploy
MIX_ENV=prod mix release
_build/prod/rel/my_app/bin/my_app eval "IO.puts(:os.type())"
_build/prod/rel/my_app/bin/my_app start
環境変数に応じた設定には config/runtime.exs を使用します。
config :my_app, MyApp.Repo,
url: System.fetch_env!("DATABASE_URL"),
pool_size: String.to_integer(System.get_env("POOL_SIZE", "10")),
ssl: true
config :my_app, MyAppWeb.Endpoint,
url: [host: System.fetch_env!("PHX_HOST"), port: 443, scheme: "https"],
http: [ip: {0,0,0,0}, port: String.to_integer(System.get_env("PORT", "4000"))],
secret_key_base: System.fetch_env!("SECRET_KEY_BASE"),
server: true
シークレット
- 環境変数またはシークレットストア(AWS/GCP KMS、Vault)を優先し、設定ファイルへの埋め込みは避けます。
mix phx.gen.secretでSECRET_KEY_BASEを生成します。
クラスタリングと PubSub/Presence
自動ノード検出には libcluster を追加します。
# mix.exs deps
{:libcluster, "~> 3.3"},
{:phoenix_pubsub, "~> 2.1"},
# application.ex
topologies = [
dns_poll: [
strategy: Cluster.Strategy.DNSPoll,
config: [poll_interval: 5_000, query: "my-app.internal"],
connect: {:net_adm, :ping}
]
]
children = [
{Cluster.Supervisor, [topologies, [name: MyApp.ClusterSupervisor]]},
{Phoenix.PubSub, name: MyApp.PubSub},
MyAppWeb.Endpoint
]
ガイドライン
- セッション署名の一貫性を保つため、ノード間で
secret_key_baseを共有します。 - Presence には分散 PubSub を使用します。Presence を多用する機能を有効にする前に、ノード間の接続を確認します。
- ブルー/グリーンデプロイでは、バージョン間で Cookie の互換性を維持します。
テレメトリ、ログ、メトリクス
- トレース/メトリクスには
opentelemetry_phoenixとopentelemetry_ectoをインストールします。 Plug.TelemetryとLoggerJSON、または構造化ログを追加します。- VM の統計情報(削減数、メモリ、スケジューラー)には、
:telemetry_pollerを介してメトリクス(Prometheus/OpenTelemetry)をエクスポートします。 - 本番環境では
LOGGER_LEVEL=infoを設定し、:debugはトラブルシューティング時のみ使用します。
HTTP とネットワークのセキュリティ強化
- HTTPS(
force_ssl)、HSTS、安全な Cookie(same_site、secure)、適切なcontent_security_policyを適用します。 - CORS:API のオリジンに合わせて
cors_plugを設定します。 - レート制限:プラグ(ETS/Cachex のトークンバケット)またはエッジ(NGINX/Cloudflare)で適用します。
- アップロード:署名付き URL を優先し、リクエスト本文のサイズ(
:max_request_line_length、:max_header_value_length)を制限します。
アセットと静的ファイルの配信
mix assets.deployは npm/tailwind/esbuild を実行し、アセットにダイジェストを付与します。- CDN/リバースプロキシ経由で静的ファイルを配信し、Endpoint で
cache-controlヘッダーが設定されていることを確認します。 - 本番環境では、イメージサイズを抑えるため、使用していないウォッチャーを無効にします。
バックグラウンドジョブ
- リトライ/バックオフ、スケジュール済みジョブ、分離には Oban を推奨します。
application.exでスーパーバイズします。 - キューはランタイム環境変数で設定し、Oban Web/Pro またはテレメトリで監視します。
- CPU 負荷の高いタスクでは、スケジューラーをブロックしないよう、プールまたは外部ワーカーを検討します。
デプロイパターン
- コンテナー:マルチステージビルドを使用し、
mix deps.get --only prod、mix compile、mix assets.deploy、続いてmix releaseを実行します。 - Systemd:リリースバイナリをサービスとして実行し、シークレットには
Environment=を使用します。Restart=on-failureを追加します。 - Fly/Gigalixir/Render:環境変数を設定し、Postgres/Redis を接続して、長時間接続の WebSocket ポートを開放します。
- ブルー/グリーンまたはカナリア:DB マイグレーションとの互換性を維持します。先にコードをデプロイしてからマイグレーションを実行し、スキーマ変更にはフィーチャーフラグを用意します。
可観測性とヘルスチェック
/healthと/readyのエンドポイント(Repo チェックと PubSub/Presence チェック)を追加します。- VM メトリクスをエクスポートします。スケジューラーの使用率とメモリを取得するために
:telemetry_pollerを実行します。 - エラー率、DB タイムアウト、キューの深さ、VM メモリについてアラートを設定します。
よくある落とし穴
PHX_SERVER=trueを設定せずにリリースをビルドする(Endpoint が起動しません)。config/runtime.exsのランタイム設定が不足しており、シークレットにコンパイル時設定を頼っている。- クラスタ検出を設定していないため、ノード間で Presence に不整合が生じる。
- デフォルトの
secret_key_baseまたはノードごとのキーを使い続け、デプロイ後にセッションが無効になる。 - ダイジェスト/CDN のない大きなアセットにより、初回読み込みが遅くなる。
コメント
Markdown 対応