Communitygithub.com

tkubica12/skill-aca-web-publish

ACA Web Publish スキルは、Azure Blob Storage を公開せずに、Azure Container Apps 上でプライベートな静的コンテンツを安全にホスティングします。

skill-aca-web-publish とは?

このスキルは、Azure 上にプライベートな静的 Web サイトをデプロイするための完全なソリューションを提供します。主な処理の流れは、静的コンテンツをプライベートな Azure Blob Storage に Cold 層でアップロードし、その Blob をアプリケーションレベルの認証を実装した Docker コンテナ(Azure Container Apps 上で動作)を介してストリーミング配信するというものです。これにより、エンドユーザーは Blob の直接 URL やストレージアカウントキーに一切アクセスできず、セキュリティが強化されます。認証プロバイダ(GitHub、Google、Entra ID)を柔軟に選択でき、カスタム DNS または ACA のビルトインホスト名を使用した OAuth 認証の設定手順も詳細にカバーしています。また、コンテナイメージのレジストリとして GHCR(パブリック)または ACR(プライベート)を選択でき、初期デプロイから運用中のユーザー追加やコンテンツ更新といった Day-2 オペレーションまでを包括的にガイドします。

対応~Claude Code~Codex CLI~Cursor
npx skills add tkubica12/skill-aca-web-publish

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

ACA Web Publish

このスキルを使用して、Blob Storage を公開せずに Azure 上でプライベートな静的コンテンツをデプロイします。デフォルトのパターンは次のとおりです。

  1. 静的コンテンツはプライベートな Azure Blob Storage にアップロードされ、Cold 層に設定されます。
  2. 小さな Docker イメージが Azure Container Apps (ACA) 上で実行されます。
  3. コンテナはアプリケーションレベルの認証を実装し、ACA を介して Blob コンテンツをストリーミングします。
  4. ACA はシステム割り当てマネージド ID と Storage Blob Data Reader ロールを使用します。
  5. ブラウザユーザーは Blob キー、SAS URL、直接 Blob URL、またはストレージアカウントキーを受け取ることはありません。
  6. ACA Easy Auth は使用しません。

必須の対話モデル

ユーザーがすべての選択肢を明示的に提供していない限り、実装前に ask_user ツールを使用してください。次の情報を収集します。

判断項目推奨されるデフォルト値
認証プロバイダGitHub
許可ユーザーデフォルトなし; 空の場合、誰もサインインできません
レジストリモードリポジトリがパブリックパッケージをホストできる場合は GHCR パブリックイメージ; ソリューションがプライベート/自己完結型である必要がある場合は ACR
カスタム DNSユーザーが Azure DNS ゾーンを持っている場合はカスタム DNS を優先
コンテンツディレクトリローカルパスを確認
Azure リソース名安全なデフォルトを生成しますが、既存のインフラを変更する前に確認します

OAuth クライアント ID またはシークレットを尋ねる前に、まず最終的な公開ホスト名が既に判明しているかどうかを確認します。

  • カスタム DNS の場合: 最初にホスト名と DNS ゾーンを尋ねます。次に、ユーザーにプロバイダポータルのリンクと、そのカスタムホスト名の正確なリダイレクト URL を提供してから、クライアント ID/シークレットを収集します。
  • ACA ビルトインホスト名の場合: ホスト名は ACA が存在するまで判明しないため、まだ OAuth クライアント ID/シークレットを尋ねないでください。最初にブートストラップ ACA エンドポイントを作成し、その https://<app>.<region>.azurecontainerapps.io URL を取得し、次にユーザーにプロバイダポータルのリンクと正確なリダイレクト URL を提供して、クライアント ID/シークレットを収集します。

プレースホルダー URL から OAuth アプリを作成するようにユーザーに依頼しないでください。ask_user を使用してクライアント ID/シークレットを収集します。最終応答でシークレットをエコーしたり、コミットしたりしないでください。

主要なデフォルト値

  • 認証プロバイダのデフォルトは github です。
  • サポートされている認証プロバイダ: github、google、entra、none。
  • none は明示的にパブリックまたは内部テスト用のデプロイメントのみに使用します。
  • 認証が有効で、許可ユーザーが設定されていない場合は、全員を拒否します。
  • カンマ区切りの許可ユーザーを使用します。
    • GitHub: tkubica12,octocat のようなハンドル。
    • Google: メールアドレス。
    • Entra: 実装に応じて、オブジェクト ID または UPN/メールアドレス。
  • GitHub では、多層防御としてオプションでメール許可リストを使用できますが、プライマリ ID はハンドルです。
  • ACA に Blob への VNet/プライベートエンドポイントルートがない限り、ストレージアカウントは publicNetworkAccess=Enabled のままにしておく必要があります。allowBlobPublicAccess=false および allowSharedKeyAccess=false を維持します。
  • ACA は小規模にします: 0.25 CPU と 0.5Gi メモリから開始します。
  • ACA は、アクティブな ACA/KEDA CLI サーフェスでサポートされている場合は 60 分のクールダウン/アイドル動作でゼロにスケーリングする必要があります。それ以外の場合は、最小レプリカを 0 に設定し、制限事項を文書化します。

レジストリの選択

GHCR モード

イメージにプロキシ/認証コードのみが含まれ、コンテンツが含まれない場合は、GHCR を使用します。ACA が資格情報なしでプルできるように、イメージ/パッケージはパブリックである必要があります。assets/publish-web-image.yml から GitHub Actions ワークフローを作成して、イメージをビルドおよびプッシュします。

ACR モード

ユーザーが完全にプライベートで自己完結型の Azure ソリューションを望む場合は、ACR を使用します。ACR を作成し、イメージをビルドまたはプッシュし、ACA マネージド ID に AcrPull を付与します。

ACR の場合、AcrPull が構成される前に、プライベートイメージから直接 ACA を作成しないでください。最初にパブリックブートストラップイメージとシステム割り当て ID を使用してアプリを作成し、その ID に AcrPull を付与し、--identity system でレジストリを構成してから、アプリを ACR イメージに更新します。

Windows ターミナルから az acr build を使用してビルドする場合は、Azure CLI ログストリーミングの Unicode/コンソールエンコーディングの失敗を避けるために --no-logs を使用します。代わりにビルド結果をクエリします。

OAuth ホスト名のタイミング

OAuth アプリ登録では、ホームページ/オリジンとコールバック URL にブラウザから見える最終的なホストを使用する必要があります。

カスタム DNS フロー

  1. カスタムホスト名と DNS ゾーンを尋ねます。
  2. プロバイダ登録リンクと正確な URL(例: https://site.example.com および https://site.example.com/oauth/github/callback)を表示します。
  3. クライアント ID とシークレットを収集します。
  4. ACA、DNS、認証設定、コンテンツ、および証明書バインディングをデプロイします。

ACA ビルトインホスト名フロー

  1. 最初にブートストラップ ACA エンドポイントをデプロイして、ビルトインホスト名を確認します。-BootstrapOnly を使用したデプロイスクリプトを使用するか、ACA/コンテナアプリのシェルを手動で作成します。
  2. 確認されたホスト名を使用して、プロバイダ登録リンクと正確な URL(例: https://<fqdn> および https://<fqdn>/oauth/github/callback)を表示します。
  3. クライアント ID とシークレットを収集します。
  4. 認証設定を適用し、コンテンツをアップロードし、アプリがブートストラップされていた場合はプロキシイメージに切り替えて、デプロイを完了します。

コピーまたは適合が必要なファイル

これらのアセットを実装の出発点として使用します。

  • assets/blob_proxy_app.py: Blob プロキシとプロバイダスイッチを備えた FastAPI アプリ。
  • assets/requirements.txt: Python ランタイム依存関係。
  • assets/Dockerfile: ACA 用の最小限のイメージ。
  • assets/deploy-aca-web.ps1: 意見が反映された Azure デプロイスクリプト。
  • assets/publish-web-image.yml: GHCR 公開用の GitHub Actions ワークフロー。

必要に応じて次のリファレンスを参照します。

  • references/architecture.md: アーキテクチャ、ストレージルール、スケーリングに関する注意事項。
  • references/auth.md: OAuth 登録手順と環境変数。
  • references/day-2.md: ユーザーの追加、シークレットのローテーション、コンテンツのアップロード、トラブルシューティング。

実装チェックリスト

  1. コンテンツディレクトリと生成されたサイトのエントリポイントを確認します。
  2. カスタム DNS または ACA ビルトインホスト名を選択します。
  3. 認証プロバイダを選択します。
  4. ホスト名が判明している場合は、ユーザーにプロバイダ固有のアプリ登録リンクと正確なコールバック URL を提供します。ACA ビルトインホスト名を使用する場合は、最初に ACA をブートストラップしてから、それらの URL を提供します。
  5. アプリ登録値を収集します。
  6. 許可ユーザーを収集します。
  7. GHCR または ACR を選択します。
  8. サンプルアプリと Dockerfile をターゲットリポジトリにコピー/適合します。
  9. GHCR モードの場合は、ワークフローを追加し、結果のパッケージをパブリックにします。
  10. ACA、プライベート Blob Storage、RBAC、シークレット、環境変数、およびオプションの DNS をデプロイします。
  11. コンテンツを Blob にアップロードし、Cold 層を設定します。
  12. スモークテストを実行します。
    • 認証されていないリクエストは、AUTH_PROVIDER=none でない限り、プロバイダにリダイレクトされます。
    • 許可されたユーザーは index.html を読み込めます。
    • 許可されていないユーザーは 403 を受け取ります。
    • メディアの範囲リクエストは 206 Partial Content を返します。
    • Blob への直接匿名アクセスは失敗します。

Day-2 タスクの処理

「ユーザーの追加」の場合、ALLOWED_USERS またはプロバイダ固有の許可リスト環境変数のみを更新し、ACA を再起動/改訂します。

「新しいコンテンツのアップロード」の場合、ローカルの静的出力を再生成し、ローカル出力が信頼できる場合にのみ削除を有効にして Blob 同期を実行し、次に Cold 層を設定します。

大きなサイトや多数のファイルの場合は、AzCopy を優先します。AzCopy が利用できず、サイトが小さい場合は、Azure CLI az storage blob upload-batch --auth-mode login が許容できるフォールバックです。大きなサイトの場合は、最初に AzCopy をインストールするか、-InstallAzCopy を使用してデプロイスクリプトを使用します。

「認証プロバイダの切り替え」の場合、最初に新しいプロバイダ登録を作成し、シークレット/環境変数を設定し、ログインを確認してから、古いプロバイダのシークレットを削除します。

「GHCR から ACR への移行」の場合、ACR をデプロイし、AcrPull を付与し、イメージ参照を更新し、Blob コンテンツは変更しません。

関連スキル