Next.jsとGithubActionsでFirebaseのCI/CDする
はじめに
Next.js を Firebase にホスティングをした際にネットの情報があまりきれいにまとまっておらず、2 回目の私でも苦戦をしてしまったので今回はハンズオン形式でまとめます。
このハンズオンでは難しい CD の部分を中心に解説していきます。CI は簡単に設定できるので、そちらは割愛します。
事前準備
Next.js のプロジェクトを Firebase にホスティングした状態からハンズオンを始めていきます
開発環境
- Next.js 14.0.1
- Firebase Cli 12.4.7
- Node.js v18.16.0
今回のゴール
Github Actions を使ってクーロンで Firebase に自動でデプロイするような環境を作ります。
ファイルをすこし変更することで Push 時に自動でデプロイするようにもできます。
1. Firebase のサービスアカウントの作成
Firebase のデプロイには、Firebase や Cloud Run などデプロイに必要な権限をもったサービスアカウントが必要です。
GCPを開いて、今回使っている Firbase のプロジェクトを選択します。
左メニューから「IAM と管理」→「サービスアカウント」を選択します。
「サービスアカウントを作成」を選択します。
サービスアカウント名を入力(ここでは firebase-cicd にしました)して「作成して続行」を選択します。
ロールを選択をクリックして以下のロールを追加します。
- Firebase Develop 管理者
「完了」を選択します。
作ったサービスアカウントの三点をクリックして、「鍵を管理」を選択します。
「鍵を追加」-> 「新しい鍵を作成」を選択します。
「作成」を選択します。
すると、json ファイルがダウンロードされます。
次に左メニューから「IAM」を選択します
作成したサービスアカウントを選択して鉛筆マークをクリックします。
「別のロールを追加」を選択します。
「iam.serviceAccountUser」を追加します。
「保存」を選択します。
ちなみにこの手順をやらないと以下のエラーに苦しむことになります。
2. Github Actions の設定
Github のリポジトリに移動して、「Settings」を選択します。
左メニューから「Security and variables」-> 「Actions」を選択します。
「New repository secret」を選択します。
- Name に
FIREBASE_KEY
を入力
value に先程ダウンロードした json ファイルを Base64 エンコードしたものを入力します。(ファイル名は firebase-cicd.json とします)
Ubuntu の場合は xsel をインストールして以下を実行します。
$ base64 firebas-cicd.json | xsel --clipboard --input
ここで注意は Base64 ファイルのコピーするときに最後が空行になるということです。これを忘れるとデコードができなくなります。
「Add secret」を選択します。
(最後が空行になっている)
次に同じ要領で、
- name:
FIREBASE_PROJECT_ID
- value: Firebase のプロジェクト ID
を設定します。
プロジェクト ID は Firebase のコンソールから確認できます。URL の中に書いてあるので確認してください。
3. Github Actions の設定
次に、リポジトリに .github/workflows
ディレクトリを作成し、その中に main.yml
を作成します。
$ mkdir -p .github/workflows
$ touch .github/workflows/main.yml
main.yml
に以下のように記述します。
name: Scheduled deploy
on:
schedule:
- cron: "0 6 * * *"
workflow_dispatch:
jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: "18"
- name: Install dependencies
run: npm install
- name: Run build
run: npm run build
deploy:
name: deploy
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js and cache
uses: actions/setup-node@v2
with:
node-version: "18"
cache: "npm"
- name: Install firebase-tools
run: npm install --save-dev firebase-tools
- name: Decode Firebase service account key
run: |
echo "${{ secrets.FIREBASE_KEY }}" | base64 -d > ./firebase-key.json
echo "GOOGLE_APPLICATION_CREDENTIALS=${{ github.workspace }}/firebase-key.json" >> $GITHUB_ENV
- name: change space
run: ./node_modules/.bin/firebase use ${{ secrets.FIREBASE_PROJECT_ID }}
- name: Deploy to Firebase Hosting
run: |
./node_modules/.bin/firebase deploy
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
FIREBASE_CLI_EXPERIMENTS: webframeworks
- name: delete GOOGLE_APPLICATION_CREDENTIALS
run: rm $GOOGLE_APPLICATION_CREDENTIALS
if: ${{ always() }}
これで、毎日 6 時にデプロイされるようになります。
Github に Push をして確認をします
4. CD の確認をする
Github の Actions に移動して、デプロイが成功しているか確認します。
左から「Scheduled deploy」を選択します。
「Run workflow」-> 「Run workflow」を選択します。
実行されたアクションをクリックします。
以下の状態になれば成功です。
ex. Push 時にデプロイする
main.yml
を変更します
name: Scheduled deploy
on:
push:
workflow_dispatch:
jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: "18"
- name: Install dependencies
run: npm install
- name: Run build
run: npm run build
deploy:
name: deploy
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js and cache
uses: actions/setup-node@v2
with:
node-version: "18"
cache: "npm"
- name: Install firebase-tools
run: npm install --save-dev firebase-tools
- name: Decode Firebase service account key
run: |
echo "${{ secrets.FIREBASE_KEY }}" | base64 -d > ./firebase-key.json
echo "GOOGLE_APPLICATION_CREDENTIALS=${{ github.workspace }}/firebase-key.json" >> $GITHUB_ENV
- name: change space
run: ./node_modules/.bin/firebase use ${{ secrets.FIREBASE_PROJECT_ID }}
- name: Deploy to Firebase Hosting
run: |
./node_modules/.bin/firebase deploy
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
FIREBASE_CLI_EXPERIMENTS: webframeworks
- name: delete GOOGLE_APPLICATION_CREDENTIALS
run: rm $GOOGLE_APPLICATION_CREDENTIALS
if: ${{ always() }}
おわりに
私がやっているプログラミングコーチング JISOU では、React+Firebase を推奨しており、CI/CD ができることはとても重要です。
今回は CD だけの設定になっていますが、CI の設定も簡単にできるので、ぜひ試してみてください。
参考
Discussion