👌
【Firebase Hosting】複数(マルチ)サイト構築・運用
前提
-
firebase init hosting
を実行完了していること
サイト構築
サイト一覧表示
まず、サイト一覧を表示してみる。
firebase hosting:sites:list
サイト追加
サイト追加してみる。
siteId="privacy"
firebase hosting:sites:create $siteId
追加したサイトの ID に対して、Target 名を紐付ける
.firebaserc へ紐付け設定追加
コマンド実行すると、自動で設定追加されます。
siteId="privacy"
targetName="privacy"
firebase target:apply hosting $targetName $siteId
.firebaserc の実例
.firebaserc
{
"projects": {
"default": "<Firebaseプロジェクト名>"
},
"targets": {
"<Firebaseプロジェクト名>": {
"hosting": {
"resume": [
"resume-<ランダム英数文字>"
],
"privacy": [
"privacy-<ランダム英数文字>"
],
"namecard": [
"namecard-<ランダム英数文字>"
]
}
}
},
"etags": {}
Target 名と「ホスティング対象ディレクトリ」を紐付ける
firebase.json へ紐付け設定追加
手動で設定追加する必要があります。
public 属性に「Firebase Hosting へデプロイしてホスティングしたい対象のディレクトリのパス」を指定する。
{
"hosting": [
{
"target": "privacy",
"public": "privacy",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
}
]
}
firebase.json の実例
firebase.json
{
"hosting": [
{
"target": "resume",
"public": "resume",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
},
{
"target": "privacy",
"public": "privacy",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
},
{
"target": "namecard",
"public": "namecard/build/web",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
],
"emulators": {
"hosting": {
"port": 5003
},
"ui": {
"enabled": true
},
"singleProjectMode": true
}
}
デプロイ
エミュレータで事前確認
まずは、ローカル環境のエミュレータでプレビュー確認してみる。
targetName="privacy"
firebase emulators:start --only hosting:$targetName
追加したサイトの channel preview へデプロイ
次に、リモート環境(Firebase Hosting 側の環境)でプレビュー確認してみる。
targetName="privacy"
channelName=$targetName
echo firebase hosting:channel:delete ${channelName} -f
firebase hosting:channel:deploy ${channelName} --only ${targetName} --expires 1h
追加したサイトへデプロイ
エミュレータと channel preview のプレビュー確認で問題なければ、本番サイトへデプロイしてみる。
targetName="privacy"
firebase deploy --only hosting:$targetName
サイト無効化・削除
追加したサイトの無効化
削除とは別。
有効化は、ロールバック or 再デプロイで実現する様子。
siteId="privacy"
firebase hosting:disable -s $siteId
サイト削除
siteId="privacy"
firebase hosting:sites:delete $siteId
サイト運用
シェルスクリプトを利用したデプロイ
channel preview(複数)へデプロイし分けるシェルスクリプト
function hosting_channel_preview_deploy() {
# 標準入力(キーボード)から1行受け取って変数strにセット
#
echo "Target No ----------"
echo "1. resume"
echo "2. privacy"
echo ""
read -p "Target No? > " str
# 変数strの内容で分岐
case "$str" in
1)
targetName="resume"
# siteId="既存のchannel previewを削除してから再デプロイしたい場合、ここにサイトIDを指定"
;;
2)
targetName="privacy"
# siteId="既存のchannel previewを削除してから再デプロイしたい場合、ここにサイトIDを指定"
;;
*)
echo "undefined"
exit
;;
esac
channelName=$targetName
# 既存のchannel previewを削除してから再デプロイしたい場合
echo firebase hosting:channel:delete ${channelName} --site ${siteId} -f
firebase hosting:channel:deploy ${channelName} --only ${targetName} --expires 1h
}
hosting_channel_preview_deploy
本番サイト(複数)へデプロイし分けるシェルスクリプト
function hosting_deploy() {
# 標準入力(キーボード)から1行受け取って変数strにセット
#
echo "Target No ----------"
echo "1. resume"
echo "2. privacy"
echo ""
read -p "Target No? > " str
# 変数strの内容で分岐
case "$str" in
1)
targetName="resume"
;;
2)
targetName="privacy"
;;
*)
echo "undefined"
exit
;;
esac
firebase deploy --only hosting:$targetName
}
hosting_deploy
GitHub Actions を利用したデプロイ
dev ブランチへ push した時、Firebase Hosting の Channel Preview へデプロイする(各サイト毎に)
.github/workflows/firebase-hosting-merge_dev.yml
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools
name: Deploy to Firebase Hosting channelId dev
"on":
push:
branches:
- dev
jobs:
if_push_origin_dev_resume:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: "${{ secrets.GITHUB_TOKEN }}"
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_<Firebaseプロジェクト名> }}"
projectId: <Firebaseプロジェクト名>
target: "resume"
channelId: "resume"
expires: "1h"
if_push_origin_dev_privacy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: "${{ secrets.GITHUB_TOKEN }}"
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_<Firebaseプロジェクト名> }}"
projectId: <Firebaseプロジェクト名>
target: "privacy"
channelId: "privacy"
expires: "1h"
dev ブランチへ push 後、pull request を作成した時、Firebase Hosting の Channel Preview へデプロイする(各サイト毎に)
.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 channelId prX-dev
"on": pull_request
jobs:
if_create_pr_resume:
if: "${{ github.event.pull_request.head.repo.full_name == github.repository }}"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: "${{ secrets.GITHUB_TOKEN }}"
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_<Firebaseプロジェクト名> }}"
projectId: <Firebaseプロジェクト名>
target: "resume"
channelId: ""
expires: "1h"
if_create_pr_privacy:
if: "${{ github.event.pull_request.head.repo.full_name == github.repository }}"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: "${{ secrets.GITHUB_TOKEN }}"
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_<Firebaseプロジェクト名> }}"
projectId: <Firebaseプロジェクト名>
target: "privacy"
channelId: ""
expires: "1h"
pull request クローズした時、Firebase Hosting の 本番サイト へデプロイする(各サイト毎に)
.github/workflows/firebase-hosting-merge_main.yml
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools
name: Deploy to Firebase Hosting channelId live
"on":
pull_request:
types:
- closed
jobs:
if_pr_merged_resume:
if: "${{ github.event.pull_request.merged == true }}"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: "${{ secrets.GITHUB_TOKEN }}"
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_<Firebaseプロジェクト名> }}"
projectId: <Firebaseプロジェクト名>
target: "resume"
channelId: live
if_pr_merged_privacy:
if: "${{ github.event.pull_request.merged == true }}"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: "${{ secrets.GITHUB_TOKEN }}"
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_<Firebaseプロジェクト名> }}"
projectId: <Firebaseプロジェクト名>
target: "privacy"
channelId: live
Discussion