Cloud Build を使って Firebase Hosting に自動デプロイ

どうも、たくチャレ(@takuchalle)です。

このブログをFirebase Hostingに移行した記事を書きました。

自動ビルド・デプロイする部分は長くなりそうだったので、この記事にまとめることにしました。

今回はCloud Buildを使って、自動ビルド・デプロイを行うようにしました。TravisCICircleCIでも同じことはできますが、Firebase Hostingを使っているので今回は Google のサービスで完結させようと思います。

(2018/10/26追記) 結局 GitLab に移行しました。

前提

Cloud Build API の有効化

まず、Cloud Build API を有効化します。

初めて Cloud Build の設定画面を開くと次のような画面になってると思うので、Enable Cloud Build APIをクリックして有効化してください。

Cloud Build の設定ファイル作成

Cloud Build では、Dockerfilecloudbuild.yamlが設定ファイルとして使えます。今回は新規で作成するのでcloudbuild.yamlを作ります。 すでにDockerfileがある場合はそれを使ってもいいと思いますので、この節は飛ばしても構いません。

ビルドの流れ

実際に設定ファイルを作成する前に、まずビルドの流れを確認します。hugoを使う場合は次の2ステップが必要です。

  • hugo コマンドでサイトの生成
  • Firebase Hosting へデプロイ

Cloud Build では各ステップごとにコンテナイメージを作って実行するようになります。 今回の場合だとhugoコマンドを実行するためのコンテナイメージ、Firebase Hosting にデプロイするためのコンテナイメージを作ります。

各ステップのコンテナイメージの作成

コンテナイメージは自分で作る必要はなく、GoogleCloudPlatform/cloud-buildersGoogleCloudPlatform/cloud-builders-community にある場合はそれを使うことができます。 幸いなことにhugofirebaseもあるのでそれを使っていきます。

余談ですが、hugo のバージョンが古かったので0.49にアップデートするプルリクがマージされました。こういう地味なOSS貢献も大事です。

$ git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
$ cd cloud-builders-community/hugo
$ gcloud builds submit --config cloudbuild.yaml . # 時間かかります
$ cd ../firebase
$ gcloud builds submit --config cloudbuild.yaml . # 時間かかります

gcloud builds submit --config cloudbuild.yaml .コマンドが成功するとコンテナイメージが作成されて、GCP コンソールのContainer Registryに登録されます。

これでCloud Build から gcr.io/${PROJECT_ID}/hugogcr.io/${PROJECT_ID}/firebaseが使えるようになります。1つのコマンドのために1つのコンテナイメージを作るなんて、どんだけ富豪インフラなんだって気がしますけどね笑

cloudbuild.yaml 作成(未完)

ビルドの流れとコンテナイメージが準備できたので設定ファイルを書いていきます。リポジトリのルートディレクトリにcloudbuild.yamlを次のように作成します。

steps:
- id: "Generate html"
  name: 'gcr.io/${PROJECT_ID}/hugo'
  args: ['']
- id: "Deploy to Firebase Hosting"
  name: 'gcr.io/${PROJECT_ID}/firebase'
  args: ['deploy']

stepsに先ほど作ったコンテナイメージと引数をしていするだけで順番に実行してくれます。hugoに引数を渡したいときはargsに記述できます。idはなくてもいいのですが、どんなステップかを表現できるので書いたほうがいいです。

この状態で実行できるか確認しましょう。

$ gcloud builds submit --config cloudbuild.yaml .

Firebase Hostingにアクセスする権限がないのでデプロイが失敗するはずです。それ以前で失敗している場合はエラーを読んで解決しましょう。

GCP コンソールのCloud BuildBuild Historyを見ると分かるように先ほどのコマンドはクラウド上で実行されています。なので、ローカルでFiribaseにログインしている状態でもデプロイできないのです。

Firebase CI キー取得

Firebaseにログインしてない状態でデプロイするためにはキーが必要です。キーがあれば次のように引数で渡してデプロイが可能です。

$ firebase deploy --token "1/xxxxxxxxxxxxxxxxxxxxxxxxxxx"

キーを取得するには次のコマンドを使います。コマンドを打つとブラウザが開くので承認します。1/xxxxxxxxxxxxxxxxxxxxxxxxxxxの部分がキーですので、次で使うので控えておいてください。

$ firebase login:ci 
Visit this URL on any device to log in:
https://accounts.google.com/o/oauth2/auth?client_id=hogefuga
Waiting for authentication...
✔  Success! Use this token to login on a CI server:

1/xxxxxxxxxxxxxxxxxxxxxxxxxxx

このキーを使うのですが、このままcloudbuild.yamlに書いてGitHubなどの公開リポジトリに入れてしまうと誰でもあなたのFirebaseにアクセスできてしまいます。悪用されて膨大な請求額が来るかもしれません。危険ですよね。

キーの暗号化

そこでCloud KMSを使ってキーを暗号化します。 Cloud KMSは先ほどのキーみたいに一般に公開したくない秘匿情報を暗号化するときに使います。

CLOUD KEY MANAGEMENT SERVICE

先ほどのキーを環境変数として使用するので、Cloud KMSの公式ドキュメントの次の3ステップを行ってください。

  • クラウド KMS のキーリングと暗号鍵を作成する
  • Cloud Build サービス アカウントに暗号鍵へのアクセス権を付与する
  • 暗号鍵を使用して環境変数を暗号化する

暗号化したキーを次に使いますので、控えておいてください。

cloudbuild.yaml 作成(完成)

先ほど暗号化したキーをcloudbuild.yamlに組み込んで完成です。プロジェクト名やキーリング名などは自身の環境に合わせてください。

secrets:
  - kmsKeyName: projects/[プロジェクト名]/locations/global/keyRings/[キーリング名]/cryptoKeys/[キー名]
    secretEnv:
      FIREBASE_TOKEN: [暗号化したキー] 

steps:
- id: "Generate html"
  name: 'gcr.io/${PROJECT_ID}/hugo'
  args: ['']
- id: "Deploy to Firebase Hosting"
  name: 'gcr.io/${PROJECT_ID}/firebase'
  args: ['deploy']
  secretEnv: ['FIREBASE_TOKEN']

このcloudbuild.yamlをリポジトリのルートディレクトリに入れてください。

ここで再度実行できるか確認しましょう。本当にデプロイされるので気をつけてください。

$ gcloud builds submit --config cloudbuild.yaml .

ビルドのトリガーを設定

master に push したことをトリガーに登録したcloudbuild.yamlを実行するように設定します。

GCP コンソールのCloud BuildBuild Triggersを開いてリポジトリを指定します。

Trigger Settingで次の項目を設定してトリガーを追加してください。

  • Name
  • Trigger Type
  • Build Configuration

これで master に push した時にFirebase Hostingに自動でデプロイできるようになりました。

僕のブログの規模だと30秒以内にはデプロイができました。記事が増えると遅くなるとは思いますが、遅くなった時は高速化なども検討したいと思います。

まとめ

Cloud Buildを使ってFirebase Hostingに自動でデプロイができるようになりました。

Netlifyより設定する手間がかかりますが、その分柔軟に色々できそうなので挑戦していきたいと思います。SASS を使って CSS を生成したり、JSを使ってもっとリッチにしたりできるのかなとは思ってます。

参考サイト

同じカテゴリの記事