Firebaseで複数プロジェクト・複数サイトを扱う方法
Firebase の公式ドキュメントには複数サイトや複数プロジェクトを扱うそれぞれ単体の方法は書かれているのですが組み合わせた場合の方法を探したところありませんでした。また、方法の一部としてコマンドは書かれていても各種設定ファイルの内容については説明がなかったりして困ったのでその辺りについて調べた事を共有します。
Firebase CLI の初期設定
Firebase CLI リファレンス | Firebase ドキュメント
説明上必要になる知識も出てくるので簡単に紹介しておきます。
Firebase CLI を利用するには下記のコマンドで Google アカウントの認証を行う必要があります。
firebase login
認証等に問題がなければ以下のコマンドでアクセス権のあるプロジェクト一覧が確認できます。
firebase projects:list
リポジトリ等に Firebase のプロジェクトディレクトリがない場合は初期化が必要です。基本的には Hosting のサイト以外に Cloud Functions なども利用する事が多いのでリポジトリルートとする場合が多いですが、デプロイ対象となるディレクトリが明確ならサブディレクトリでも問題ないです。
firebase init
いくつかの質問のあとに firebase.json
と .firebaserc
が作成され、それぞれの役割は以下の通りです。
-
firebase.json
- Firebase の各種サービスの構成や設定を行うファイル
-
.firebaserc
- プロジェクトエイリアスと複数のデプロイターゲットを扱う際の設定を行うファイル
- プロジェクト ID が記載されるので public リポジトリの場合は
.gitignore
に登録推奨
それぞれのファイルの具体的な設定方法は後述します。
複数プロジェクト
Firebase CLI リファレンス | Firebase ドキュメント
開発環境、ステージング環境、本番環境のように同じ構成を異なるプロジェクトにデプロイしたい場合など、複数のプロジェクトを扱う際の設定とコマンドについての説明です。
複数のプロジェクトを扱いたい時は .firebaserc
にエイリアスの定義を追加します。
{
"projects": {
"default": "default-project-id",
"staging": "staging-project-id",
"production": "production-project-id"
}
}
エイリアスの定義は firebase use --add
コマンドによる対話形式でも追加できます。
default
は特別なエイリアス名で使用するプロジェクトの切り替えを行っていない場合に使用されるプロジェクトです。複数のプロジェクトを扱う際は操作ミスなども考慮して default
は別名に変えておいた方が安全です。
firebase use <PROJECT_ID | ALIAS>
プロジェクトの切り替えは上記のコマンドで行います。firebase use staging
と定義したエイリアスを使う以外にプロジェクトIDを指定する事もできます。
プロジェクトを切り替えると以降に実行するコマンドはそのプロジェクトに対して適用されます。また、firebase deploy --project=staging
のように --project
オプションでコマンド単位で対象プロジェクトを変更する事もできます。
複数サイト
Firebase CLI リファレンス | Firebase ドキュメント
デプロイ ターゲット | Firebase ドキュメント
ホスティング動作を構成する | Firebase Hosting
複数のサイト間でプロジェクトリソースを共有する | Firebase Hosting
1 プロジェクトで複数のサイトを扱うにはデプロイターゲットの設定を行います。この機能自体は Firebase Hosting に限らず Functions や Storage など他のサービスも含めて複数のターゲットを扱う為の機能なのでサイト以外も同様の設定で行えます。
設定を行う前にまず先にリソースを作成します。Hosting のサイトの場合は Firebase の Web コンソールもしくは下記のコマンドで作成できます。site-id
はグローバルで一意である事が必須です。
firebase hosting:sites:create <site-id>
サイトが作成できたらデプロイターゲットとして設定します。設定は下記のコマンドもしくは .firebaserc
を直接編集する事で行えます。
firebase target:apply <type> <target-name> <resource-identifier>
-
type
: hosting や functions など Firebase のリソースの種類 -
target-name
: 作成するターゲットの名前 -
resource-identifier
: site-id などリソースを識別する為の ID
.firebaserc
を直接編集する場合の構造は以下の通りです。
上記のコマンドの target-name
が main
と admin
でそれぞれに対応する resource-identifier
が main-site-id
と admin-site-id
の場合に相当します。
{
"projects": {
"default": "default-project-id"
},
"targets": {
"default-project-id": {
"hosting": {
"main": [
"main-site-id"
],
"admin": [
"admin-site-id"
]
}
}
}
}
firebase-tools/src/rc.ts at master · firebase/firebase-tools
補足: TypeScript の型定義は以下のようになっています。
export interface RCData {
projects: { [alias: string]: string };
targets: {
[projectId: string]: {
[targetType: string]: {
[targetName: string]: string[];
};
};
};
etags: {
[projectId: string]: Record<EtagResourceType, Record<string, string>>;
};
}
デプロイターゲットの設定が出来たら firebase.json
にそれぞれのターゲットの構成を設定します。hosting
の値を配列にして .firebaserc
の target-name
と .firebaserc
の target
の値が対応するように設定して下さい。
{
"hosting": [
{
"target": "main",
"public": "packages/main/dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
},
{
"target": "admin",
"public": "packages/admin/dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
}
]
}
以上の設定で firebase deploy
時に複数のサイトがデプロイできるようになります。また、特定のサイトのみをデプロイしたい時は firebase deploy --only hosting:TARGET_NAME
で指定する事ができます。
複数サイト x 複数プロジェクト
デプロイ ターゲット | Firebase ドキュメント
ホスティング動作を構成する | Firebase Hosting
複数のサイト間でプロジェクトリソースを共有する | Firebase Hosting
複数サイトを複数プロジェクトに対応するには .firebaserc
の targets
にプロジェクトのデプロイターゲットの定義を追加する事で行えます。
{
"projects": {
"default": "default-project-id",
"staging": "staging-project-id"
},
"targets": {
"default-project-id": {
"hosting": {
"main": [
"main-site-id"
],
"admin": [
"admin-site-id"
]
}
},
"staging-project-id": {
"hosting": {
"main": [
"staging-main-site-id"
],
"admin": [
"staging-admin-site-id"
]
}
}
}
}
上記は複数サイトで紹介した設定例に staging 用のプロジェクトを追加した設定例です。
site-id
はグローバルで一意になっているので各プロジェクトのデプロイターゲットをどの site-id
にデプロイするのかの対応付けをここで行う形です。
基本的にはこれで設定が完了し firebase use
で切り替えるか firebase deploy --project
でプロジェクトを指定すれば、複数サイトを別プロジェクトにデプロイする事が出来るようになります。
ただし、Cloud Run と連携させている場合には注意が必要です。Cloud Run と連携するには firebase.json
の hosting.rewrites
の設定を以下のように定義します。
{
"hosting": [
{
"target": "main",
"public": "packages/main/dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "/api",
"run": {
"serviceId": "api-server",
"region": "asia-northeast1"
}
}
]
},
]
}
serviceId
に Cloud Run で動作させているサービス名を指定するので複数のプロジェクトで運用する際には全てのプロジェクトで同じサービス名にする必要があります。異なるサービス名をつける運用も可能ですが、プロジェクトが増える毎にサイト数分の hosting target の設定を追加する事になるので、扱うサイト数とプロジェクト数が固定でない限りは避けた方がいいでしょう。例えば、main
と admin
があるサイトの構成だとプロジェクトが増える毎に project-name-main
と project-name-admin
の設定を firebase.json
に追加し、.firebaserc
にその対応付けを追加して行くことになります。
Discussion