HugoをFirebase Hosting + Cloud Buildで動かす
Last updated: 2019-08-30
Hugoでサイトを作ってGitHub + Cloud BuildでFirebaseに反映するまでの概要説明の記事です。
Hugoのインストール
Install Hugo | Hugoを参考に、Hugoを導入する。 (WSLを使いたかったものの、LiveReload(Markdownを自動的にリビルドしページを表示してくれる)が動かなかったのでWindows/PowerShellで使う事にした)
Releases · gohugoio/hugoから 「hugo_0.57.2_Windows-64bit.zip」をダウンロードし、適当な所においてパスを通す。バイナリ一個だけで動いてくれる。
コマンドhugo version
でバージョン情報が表示されればOK。
PS C:\home\sitesfiles\Firebase> hugo version
Hugo Static Site Generator v0.57.2-A849CB2D windows/amd64 BuildDate: 2019-08-17T17:54:13Z
Hugoサイトの作成
コマンドhugo new site サイト名
でサイトを作る。
PS C:\home\sitesfiles\Firebase> hugo new site samplesite
Congratulations! Your new Hugo site is created in C:\home\sitesfiles\Firebase\samplesite.
Just a few more steps and you're ready to go:
1. Download a theme into the same-named folder.
Choose a theme from https://themes.gohugo.io/ or
create your own with the "hugo new theme <THEMENAME>" command.
2. Perhaps you want to add some content. You can add single files
with "hugo new <SECTIONNAME>\<FILENAME>.<FORMAT>".
3. Start the built-in live server via "hugo server".
Visit https://gohugo.io/ for quickstart guide and full documentation.
gitの初期化とテーマの取得を行う。
テーマはオフィシャルのサイト
Complete List | Hugo Themes
から検索できる。自分は
Cupper Hugo Theme | Hugo Themes
気に入ったのでそれを選びました。
はじめて使ったが、テーマは別管理なのでgit submodule add
するといいみたい。
(といいつつCloud Buildの所ではまったが…)
PS C:\home\sitesfiles\Firebase> cd .\samplesite\
PS C:\home\sitesfiles\Firebase\samplesite> git init
Initialized empty Git repository in C:/home/sitesfiles/Firebase/samplesite/.git/
PS C:\home\sitesfiles\Firebase\samplesite> git submodule add https://github.com/zwbetz-gh/cupper-hugo-theme ./themes/cupper-hugo-theme
Cloning into 'C:/home/sitesfiles/Firebase/samplesite/themes/cupper-hugo-theme'...
remote: Enumerating objects: 7493, done.
remote: Total 7493 (delta 0), reused 0 (delta 0), pack-reused 7493
Receiving objects: 100% (7493/7493), 11.94 MiB | 2.85 MiB/s, done.
Resolving deltas: 100% (4254/4254), done.
warning: LF will be replaced by CRLF in .gitmodules.
The file will have its original line endings in your working directory.
「\themes\cupper-hugo-theme\exampleSite」以下にサンプルのサイト用のファイルがあるので、中身を全部サイト直下にコピーする。
(さくっとCopy-Item -Recurse .\themes\cupper-hugo-theme\exampleSite\* .\
で行きたかったがフォルダーの有無でエラーがでるようなのでエクスプローラーで普通にコピー(>_<))
Hugoサイトのローカル起動
後は、hugo server -D
でサーバーを起動させるとサイトが
http://localhost:1313/
で確認できる。
この時点で
http://localhost:1313/about/をブラウザで表示しておいて、
「\content\about.md」の変更と保存を行うとブラウザ側に自動で反映される。
すごいね。
PS C:\home\sitesfiles\Firebase\samplesite> hugo server -D
Building sites …
| EN
+------------------+----+
Pages | 48
Paginator pages | 0
Non-page files | 4
Static files | 33
Processed images | 4
Aliases | 0
Sitemaps | 1
Cleaned | 0
Total in 1218 ms
Watching for changes in C:\home\sitesfiles\Firebase\samplesite\{archetypes,content,data,layouts,static,themes}
Watching for config changes in C:\home\sitesfiles\Firebase\samplesite\config.toml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop
次の手順でファイルをアップロードするので、先に公開用の静的ファイルを作っておく。
PS C:\home\sitesfiles\Firebase\samplesite> hugo
Building sites …
| EN
+------------------+----+
Pages | 48
Paginator pages | 0
Non-page files | 4
Static files | 33
Processed images | 4
Aliases | 0
Sitemaps | 1
Cleaned | 0
Total in 517 ms
Firebaseの設定
Firebase consoleでプロジェクトを作成する。 途中Google Analyticsとの連携を聞かれたが、とりあえずチェックを入れて先に進めた。
コマンドベースの管理ツールFirebase CLIをインストールする(Node.jsが古かったためNode.js で最新を落としてからインストールを進めた)。
以下のようにfirebsaseを使ってログインできる。
PS C:\home\sitesfiles\Firebase\samplesite> npm install -g firebase-tools
PS C:\home\sitesfiles\Firebase\samplesite> firebase login
PS C:\home\sitesfiles\Firebase\samplesite> firebase list
HugoサイトのルートでFareBaseの初期化をfirebase init
で行う。
結構色々聞かれる。
Firebaseのどの機能を使うか=>Hostingのみをチェックする。
PS C:\home\sitesfiles\Firebase\samplesite> firebase init
######## #### ######## ######## ######## ### ###### ########
## ## ## ## ## ## ## ## ## ## ##
###### ## ######## ###### ######## ######### ###### ######
## ## ## ## ## ## ## ## ## ## ##
## #### ## ## ######## ######## ## ## ###### ########
You're about to initialize a Firebase project in this directory:
C:\home\sitesfiles\Firebase\samplesite
Before we get started, keep in mind:
* You are currently outside your home directory
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices.
( ) Database: Deploy Firebase Realtime Database Rules
( ) Firestore: Deploy rules and create indexes for Firestore
( ) Functions: Configure and deploy Cloud Functions
>(*) Hosting: Configure and deploy Firebase Hosting sites
( ) Storage: Deploy Cloud Storage security rules
Firebaseのプロジェクトとどう関連付けするか⇒既存のプロジェクトを使う。
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. Hosting: Configure and deploy Firebase Hosting sites
=== Project Setup
First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.
? Please select an option: (Use arrow keys)
> Use an existing project
Create a new project
Add Firebase to an existing Google Cloud Platform project
Don't set up a default project
Firebaseのプロジェクトを選択する。
=== Project Setup
? Please select an option: Use an existing project
? Select a default Firebase project for this directory:
> firebase-sample-project (firebase-sample-project)
公開するディレクトリは何にするか⇒publicにする。
シングルページのアプリケーションか⇒Noにする。
ローカルファイルの上書きを聞かれる⇒Noにする。
=== Hosting Setup
Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.
? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No
+ Wrote public/404.html
? File public/index.html already exists. Overwrite? No
i Skipping write of public/index.html
i Writing configuration info to firebase.json...
i Writing project information to .firebaserc...
+ Firebase initialization complete!
firebase deploy
でデプロイする。
コンソールと公開したURLが表示される。
PS C:\home\sitesfiles\Firebase\samplesite> firebase deploy
=== Deploying to 'firebase-sample-project'...
i deploying hosting
i hosting[firebase-sample-project]: beginning deploy...
i hosting[firebase-sample-project]: found 92 files in public
+ hosting[firebase-sample-project]: file upload complete
i hosting[firebase-sample-project]: finalizing version...
+ hosting[firebase-sample-project]: version finalized
i hosting[firebase-sample-project]: releasing new version...
+ hosting[firebase-sample-project]: release complete
+ Deploy complete!
Project Console: https://console.firebase.google.com/project/firebase-sample-project/overview
Hosting URL: https://firebase-sample-project.firebaseapp.com
ドメイン未設定のためか、レイアウトが崩れていたがとりあえずアップロードできた。 (config.tomlのbaseURLの設定だが、この後ドメインを設定するのでそのまま)
次にコンソールのHostingにある「ドメインを接続」で使用するドメインを設定した。 画面に表示された値をTXTレコードに入れて、しばらく待つと認証が完了した。
GitHubにPrivateリポジトリを用意する
GitHubにPrivateリポジトリを作っておく。用意したHugoのサイトをpushする。
PS C:\Users> cd C:\home\sitesfiles\Firebase\samplesite
PS C:\home\sitesfiles\Firebase\samplesite> git remote add origin https://github.com/**********/*************.git
PS C:\home\sitesfiles\Firebase\samplesite> git push -u origin master
Counting objects: 32, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (27/27), done.
Writing objects: 100% (32/32), 3.81 MiB | 118.00 KiB/s, done.
Total 32 (delta 0), reused 0 (delta 0)
To https://github.com/**********/*************.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Firebaseのトークンを取得する
Croud BuildからFirebaseへの書き込みで使うため、トークンを用意しておく。
PS C:\home\sitesfiles\Firebase\samplesite> firebase login:ci
Visit this URL on any device to log in:
https://accounts.google.com/o/oauth2/auth?client_id=**********
Waiting for authentication...
+ Success! Use this token to login on a CI server:
1/***********************
Example: firebase deploy --token "$FIREBASE_TOKEN"
Google Cloud SDKのインストール
Google Cloud SDKが必要なので、インストールを行う。
Google Cloud SDK のドキュメント | Cloud SDK | Google Cloud
トークンの暗号化
取得したFirebaseのトークンを暗号化してGoogle Cloudから使いたい。
暗号化されたリソースの使用 | Cloud Build | Google Cloud
gcloud kms keyrings create [KEYRING-NAME] --location=global
を実行するとエラーが返される。
ERROR: (gcloud.kms.keyrings.create) FAILED_PRECONDITION: Google Cloud KMS API has not been used in this project before, or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudkms.googleapis.com/overview?project=************ then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
サイトにアクセスし、Cloud Key Management Service (KMS) APIを有効にして、再度実行を行う。 Google Croud SDK Shellで以下を実行する。
gcloud kms keyrings create [KEYRING-NAME] --location=global
暗号鍵を作成する。
gcloud kms keys create [KEY-NAME] --location=global --keyring=[KEYRING-NAME] --purpose=encryption
Cloud Buildサービス アカウントに暗号鍵へのアクセス権を付与
GCP Console で [IAM] メニュー にアクセスし、 Cloud Buildサービスアカウントのメールアドレス(*****@cloudbuild.gserviceaccount.com)をコピーする。
GCP Console の [暗号鍵] メニュー にアクセスし、権限]をクリックしする。 メンバーを追加をクリックし、サービス アカウントのメールアドレスを入力する。 役割プルダウンメニューから「クラウドKMS暗号鍵の復号化」を選択し、役割を追加して保存する。
暗号化したFirebaseのトークンを用意する
GCPのCloud Shellで以下を実行する。
echo -n 1/*********************** | gcloud kms encrypt --plaintext-file=- --ciphertext-file=- --location=global --keyring=[KEYRING-NAME] --key=[KEY-NAME] | base64
出てきた文字列を元に「cloudbuild.yaml」をサイトのルートに作成する。
secrets:
- kmsKeyName: projects/[PROJECT-ID]/locations/global/keyRings/[KEYRING-NAME]/cryptoKeys/[KEY-NAME]
secretEnv:
MY_SECRET: <base64-encoded encrypted secret>
steps:
- id: 'git-submodule-update'
name: 'gcr.io/cloud-builders/git'
entrypoint: 'bash'
args:
- '-c'
- |
git submodule init
git submodule update
- id: "generate-html"
name: 'gcr.io/${PROJECT_ID}/hugo'
args: ['']
waitFor: ['git-submodule-update']
- id: "deploy-to-firebase-hosting"
name: 'gcr.io/${PROJECT_ID}/firebase'
entrypoint: 'bash'
args: ['-c', 'firebase deploy --token "$$PASSWORD"']
secretEnv: ['MY_SECRET']
Cloud Buildでデプロイを自動化する
Cloud Build - 継続的インテグレーションのためのビルドの自動化 | Cloud Build | Google Cloudから GCPのコンソールを表示する。ツールの中にCloud Buildがあるのでプロジェクトの作成を行っておく。
Cloud Build APIを有効にしようすると、
Billing must be enabled for activation of service ‘[cloudbuild.googleapis.com, containerregistry.googleapis.com]’ in project ‘*************’ to proceed
と表示される。12か月間の無料トライアルが残っていたので、請求情報の登録をした所、有効化ができた。
トリガーの設定では、以下を選んだ。
- ソースの選択 ⇒ GitHub
- 「Googleが認証トークンを収集・保存することに同意する」にチェック
- 作成しておいたデプロイ用のリポジトリを選択する
- トリガーのタイプをブランチ
- ブランチの正規表現をmaster
- ビルド設定をCloud Build構成ファイルに
- 構成ファイルの場所は/cloudbuild.yamlにした
GCPのCloud Shellで以下を実行し、ビルド用のdockerイメージを作成する これで自動Buildのステップで、git、firebase、hugoが使えるようになる。
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 .
cd ../git
gcloud builds submit --config cloudbuild.yaml .
GCPのコンソールでデプロイ用のプロジェクトが選ばれている必要があるので、 Cloud Buildが有効になっているプロジェクトが選ばれていない場合、Cloud Shellでの作業前に以下を行っておく必要がある。
gcloud config set project [deploy-project-id]
さらにローカルで作成したcloudbuild.yamlに対しても以下を行う。
gcloud builds submit --config cloudbuild.yaml .
Cloud Resource Manager APIの有効化
ここまでで、gitのプッシュを試した所、トリガーは効いている、以下のエラーとなる。 指示されたURLで機能の有効化を行う。
Step #1 - “Deploy to Firebase Hosting”: Error: HTTP Error: 403, Cloud Resource Manager API has not been used in project ******** before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/overview?project=********** then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry. Finished Step #1 - “Deploy to Firebase Hosting
これで、GitHubへのプッシュで自動的にビルドがされるようになった。
参考ページ
- Hugo で作ったブログを Firebase Hosting に移行した
- cloudbuild.yaml
- Cloud Buildを使ってHugoをビルド&デプロイする - sanpobiyori.info
- Google Cloud Build で CI/CD! ~ Firebase Hosting 編 ~ - google-cloud-jp - Medium
- Hugo, Google Cloud Build & Firebase :: jslee.io — synthesizers and other hackery
- [Git]あるはずのsubmoduleが空ディレクトリになってる場合の対処法 · DQNEO起業日記