mcpField
P
phoenix-ops

phoenix-ops

github.com/bobmatnycクラウド・DevOps78335 回インストール15 週間前に更新
リポジトリ

phoenix-ops について

Elixir/Phoenix 開発者向けの本番運用ガイドです。リリース、ランタイム設定、クラスタリング、可観測性、セキュリティ対策に加え、バックグラウンドジョブやヘルスチェック、デプロイ方法も扱います。

主な機能

  1. 01本番リリースとランタイム設定
  2. 02クラスタリング、PubSub、Presence の設計
  3. 03テレメトリー、ログ、メトリクスの設定
  4. 04HTTP エンドポイントとネットワークの強化
  5. 05バックグラウンドジョブとデプロイ方法

活用シーン

  1. 01Phoenix アプリの本番リリース準備
  2. 02ノード間の Presence 不整合の調査
  3. 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 のない大きなアセットにより、初回読み込みが遅くなる。

コメント