はじめに
1時間の音声を15秒で文字起こしし自然な会話形式に自動変換する「インタビューAI」を個人開発中。
現在、開発環境での開発をほぼ終え、本番環境への移行中。
フロントエンドはReact、バックエンドはNode.js、データベースはMongoDBで開発。
GitHub Actionsを使用してFirebase Hostingにフロントエンドを自動デプロイするための設定手順を記載しておく。
Firebaseプロジェクトの設定
Firebaseプロジェクトの作成または選択
- Firebaseコンソールにアクセスし、新しいプロジェクトを作成するか、既存のプロジェクトを選択する。
Firebase Hostingの初期化
ローカル環境でプロジェクトディレクトリ(今回はfrontend/)に移動し、以下のコマンドを実行。
firebase init
プロンプトに従って設定を進めていく
1)Hosting のオプションを選択(spaceキーを押して選択したのちにEnterキー)
2) What do you want to use as your public directory? (public) →buildと入力。
Firebase Hosting の設定時に、build
ディレクトリ(React でビルドした静的ファイルが入るディレクトリ)を公開ディレクトリとして指定
3)Configure as a single-page app (rewrite all urls to /index.html)?→Yes
React アプリケーションなのでYES。URL に関係なく、すべてのリクエストが index.html にリライトされ、クライアントサイドルーティングが正しく動作する。
他、下記のようにyes, noを選択していく。
無事設定が終わると、自動でSucessの画面が開く
Firebase Hosting の設定時に GitHub Actions を使った自動デプロイ のために、どの GitHub リポジトリを使用するかを指定を聞かれるので、「ユーザー名/リポジトリ」の形式で入力してEnter。
無事設定完了すると、デプロイ用のワークフローファイル として、firebase-hosting-merge.yml
と firebase-hosting-pull-request.yml
という2つのワークファイルが .github/workflows下に自動生成される。これはFirebase CLI が GitHub Actions のために作成したもの。以下の2つのシナリオで自動デプロイを行うための設定が含まれている。
firebase-hosting-merge.yml
:プルリクエスト(PR)が main
ブランチなどにマージされたときに自動デプロイを行う設定。
firebase-hosting-pull-request.yml
:プルリクエストが作成されたときに、プレビュー用の環境にデプロイするための設定。
interview-ai/.github/workflows/firebase-hosting-merge.yml
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools
name: Deploy to Firebase Hosting on merge
on:
push:
branches:
- main
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
channelId: live
projectId: <your-firebase-project-id>
interview-ai/.github/workflows/firebase-hosting-pull-request.yml
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools
name: Deploy to Firebase Hosting on PR
on: pull_request
permissions:
checks: write
contents: read
pull-requests: write
jobs:
build_and_preview:
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
projectId: <your-firebase-project-id>
これらのファイルは後ほど修正する。
サービスアカウントの作成とキーの取得(自動生成アップロード)
GitHub ActionsがFirebase Hostingにアクセスできるようにするために、サービスアカウントを作成する。このアカウントにFirebase Hostingへの管理者権限を与えることで、自動デプロイを実現する。
ただし、これに関しては、先ほどfirebase init hostingを行った際のログを見ると
Uploaded service account JSON to GitHub as secret FIREBASE_SERVICE_ACCOUNT.
と記載されており、すでに FIREBASE_SERVICE_ACCOUNT
というシークレット名で GitHub にサービスアカウントの JSON ファイルをアップロード済みなので、追加のサービスアカウントの作成や JSON ファイルの再ダウンロードは不要。
実際に、Githubリポジトリ→Settings→Secrets and variables→Actionsをクリックすると、GitHub SecretsにFIREBASE_SERVICE_ACCOUNT
が登録済みなことがわかる。
GitHub Actionsワークフローの修正
自動作成された2つのワークフローの下記2点を修正する
- 必要な環境変数の指定
- ワーキングディレクトリをルートディレクトリではなくfrontendを指定
環境変数の管理
ローカルで本番環境をシミュレーションする場合は.env.production
ファイルを作成し、必要な環境変数を定義する。ビルド時にこれらの変数が適用されるように設定する。.env.production
ファイルはGitリポジトリに含めないように .gitignore
に追加。
firebase関連の設定は、firebaseコンソールでアプリを作成後に、「プロジェクトの設定」→「全般」タブをスクロールすると、firebaseConfigとして表示される。
frontend/.env.production
必要な環境変数はGitHub Secretsとして追加し、ワークフロー内で安全に使用するようにする。
ワークフローファイル(例: .github/workflows/deploy-frontend.yml
)内で、シークレットを環境変数として使用するように、Build frontend
ステップで、必要な環境変数を env
キーを使って注入する。
working-directory を ./frontend に設定
また、今回はfirebase.json
(Firebaseの設定ファイル)が frontend/
ディレクトリ内にあるため、working-directory
を ./frontend
に設定し、GitHub Actions ワークフローの Deploy to Firebase Hosting
ステップで entryPoint: frontend
を追加してFirebase の設定ファイルの位置を正しく認識させる。
これで、firebase.json
ファイルの場所を正しく認識し、Firebase にデプロイできるようになる。
interview-ai/.github/workflows/firebase-hosting-merge.yml
name: Deploy Frontend to Firebase Hosting on merge
on:
push:
branches:
- main # mainブランチにマージされたときにトリガー
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18" # 使用する Node.js のバージョンを指定
- name: Install dependencies
run: npm install
working-directory: ./frontend # フロントエンドディレクトリへのパス
- name: Build frontend
run: npm run build
working-directory: ./frontend
env:
REACT_APP_FIREBASE_API_KEY: ${{ secrets.REACT_APP_FIREBASE_API_KEY }}
REACT_APP_FIREBASE_AUTH_DOMAIN: ${{ secrets.REACT_APP_FIREBASE_AUTH_DOMAIN }}
REACT_APP_FIREBASE_PROJECT_ID: ${{ secrets.REACT_APP_FIREBASE_PROJECT_ID }}
REACT_APP_FIREBASE_STORAGE_BUCKET: ${{ secrets.REACT_APP_FIREBASE_STORAGE_BUCKET }}
REACT_APP_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.REACT_APP_FIREBASE_MESSAGING_SENDER_ID }}
REACT_APP_FIREBASE_APP_ID: ${{ secrets.REACT_APP_FIREBASE_APP_ID }}
REACT_APP_BACKEND_URL: ${{ secrets.REACT_APP_BACKEND_URL }}
REACT_APP_WEBSOCKET_URL: ${{ secrets.REACT_APP_WEBSOCKET_URL }}
- name: Deploy to Firebase Hosting (Live Channel)
uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
projectId: <your-firebase-project-id>
channelId: live # 本番用ライブチャンネル
entryPoint: frontend # firebase.jsonがあるディレクトリを指定
interview-ai/.github/workflows/firebase-hosting-pull-request.yml
name: Deploy Preview to Firebase Hosting on PR
on:
pull_request:
branches:
- main
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18" # 使用する Node.js のバージョンを指定
- name: Install dependencies
run: npm install
working-directory: ./frontend # フロントエンドディレクトリへのパス
- name: Build frontend
run: npm run build
working-directory: ./frontend
env:
REACT_APP_FIREBASE_API_KEY: ${{ secrets.REACT_APP_FIREBASE_API_KEY }}
REACT_APP_FIREBASE_AUTH_DOMAIN: ${{ secrets.REACT_APP_FIREBASE_AUTH_DOMAIN }}
REACT_APP_FIREBASE_PROJECT_ID: ${{ secrets.REACT_APP_FIREBASE_PROJECT_ID }}
REACT_APP_FIREBASE_STORAGE_BUCKET: ${{ secrets.REACT_APP_FIREBASE_STORAGE_BUCKET }}
REACT_APP_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.REACT_APP_FIREBASE_MESSAGING_SENDER_ID }}
REACT_APP_FIREBASE_APP_ID: ${{ secrets.REACT_APP_FIREBASE_APP_ID }}
REACT_APP_BACKEND_URL: ${{ secrets.REACT_APP_BACKEND_URL }}
REACT_APP_WEBSOCKET_URL: ${{ secrets.REACT_APP_WEBSOCKET_URL }}
- name: Deploy to Firebase (Preview Channel)
uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT}}
projectId: <your-firebase-project-id>
channelId: preview-${{ github.event.number }} # プレビュー用チャンネルIDをPR番号で指定
entryPoint: frontend # firebase.jsonがあるディレクトリを指定
ワークフローの確認と実行
ワークフローファイルをコミットしdevelopブランチにpushしたのちに、mainブランチに対してPRを発行する。
GitHub Actionsの確認
- リポジトリの 「Actions」 タブに移動し、ワークフローの実行状況を確認する。
- デプロイが成功すると、Firebase Hostingに最新のビルドが反映される。
GitHub Actions が Firebase にデプロイする際、GitHub API を介して「チェックラン (check run)」を作成しようとしたときにGitHub Actions がリポジトリへの適切なアクセス権限を持っていないため、API リクエストが失敗したというエラーが発生。
firebase-hosting-pull-request.ymlワークフローファイルの最上部に以下を追加
permissions:
checks: write
contents: write
developにpushしてmainにPR投げると今回は成功した。
mainにmergeすると、firebase hostingに対しての自動デプロイが開始される
こちらも無事成功
Firebase Hosting サイトの URLにアクセスして、デプロイされたサイトを無事開けた。
まとめ
GitHub Actionsを活用することで、手動のデプロイ作業を効率化し、Firebase Hostingへの自動デプロイを実現可能。本記事では、Firebaseプロジェクトの設定からGitHub Actionsの構築まで、ステップごとに具体的な手順を記載した。今後はこのフローを活用し、よりスムーズなデプロイプロセスを実現したい。