勉強会用に作成した、Cloud Functions for FirebaseとFirebase Hostingを使い、ベーシック認証付きステージング環境と本番環境を用意するまでのフローです。
-
ベーシック認証付きステージング環境
- ユーザー名:
user
- パスワード:
pass
- ユーザー名:
- 本番環境
以下の内容を学ぶことができます。
- Git(GitHub)入門
- Firebase Hosting と Cloud Functions for Firebase 入門
- ほんのりTypeScript
始めるまえに、以下の設定が必要です。
- GitHubアカウント
- Googleアカウント
- ローカル環境にNode.jsのインストール(version 8 以上)
GitHubのリポジトリを作成
- 「New repository」でリポジトリを新規作成
- 「Clone or download」でURLを取得しクローン
- 任意の場所でプロジェクト用ディレクトリを作成
- クローンしたディレクトリにターミナルで移動
$ mkdir demo-project
$ git clone <github-url>
$ cd demo-projecy
developブランチの作成
ターミナルでブランチを作成
$ git checkout -b develop
ベーシック認証の環境
Firebaseのプロジェクトを作成
コンソールで新規プロジェクト作成
firebaseの設定
$ firebase login
$ firebase init
-
Functions: Configure and deploy Cloud Functions
を選択 - Firebase Consoleで作成したプロジェクトを選択
- せっかくなのでTypeScriptを選択
- Do you want to use TSLint to catch probable bugs and enforce style? -> n(TSLintよりも、ESLintが良いかと思うのでここはNoで)
- Do you want to install dependencies with npm now? -> [enter](npm installしてくれます)
開発環境の構築
リダイレクト用ホスティングディレクトリ作成
public/
└ placeholder.html
Webページの本体になるディレクトリを作成
(nuxt generate
等で出力する場合は、そのディレクトリ)
表示確認ようにダミーのindex.html
を作成しておく
functions/
└ dist/
└ index.html
package.json
とpackage-lock.json
を移動
functions/
├ package.json
└ package-lock.json
↓
functions/
package.json
package-lock.json
npm script
を書き換え
"scripts": {
"build": "tsc --project functions",
"preserve": "npm run build && npm run copy-deps && npm run install-deps",
"serve": "npm run build && firebase serve",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"init-deploy": "firebase deploy",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log",
"copy-deps": "cpx \"*{package.json,package-lock.json,yarn.lock}\" \"functions\" -C",
"install-deps": "cd functions && npm install && cd ../"
}
パッケージの追加
$ npm i express basic-auth-connect && npm i -D @types/express cpx
firebase.json
の書き換え
{
"functions": {
"source": "functions",
"predeploy": "npm run preserve"
},
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"function": "stagingApp"
}
]
}
}
function/src/index.ts
に以下を記述
import * as functions from 'firebase-functions';
import * as express from 'express';
// 型定義ファイルを作るのが面倒なので妥協。。。
const basicAuth = require('basic-auth-connect');
const user = 'user';
const pass = 'pass';
const server = express();
server.use(basicAuth(user, pass));
server.use(express.static('./dist'));
export const stagingApp = functions.https.onRequest(server);
function/src/index.ts
をビルドしてローカルサーバー立ち上げ
$ npm run serve
機密情報を環境変数に変更
このままだとベーシック認証のアイパスが見えてしまうので環境変数に格納
$ cd functions
$ firebase functions:config:set basicauth.user="<yourUserName>" basicauth.pass="<yourPassword>"
設定した環境変数は以下で確認できる
$ firebase functions:config:get
ローカルサーバーでも使えるように、functions/.runtimeconfig.json
を作成
$ firebase functions:config:get > .runtimeconfig.json
$ cd ../
.gitignore
に.runtimeconfig.json
を追加してgit管理から外す(リモートにプッシュ禁止)
また、functions/
配下にもnode_modules
やpackage.json
が必要なため、以下のコマンドで複製しインストールしておく
(ローカルサーバー立ち上げ、デプロイ時にも実行されます)
$ npm run copy-deps && npm run install-deps
function/src/index.ts
を修正
import * as functions from 'firebase-functions';
import * as express from 'express';
// 型定義ファイルを作るのが面倒なので妥協。。。
const basicAuth = require('basic-auth-connect');
// 環境変数
const user = functions.config().basicauth.user;
const pass = functions.config().basicauth.pass;
const server = express();
server.use(basicAuth(user, pass));
server.use(express.static('./dist'));
export const stagingApp = functions.https.onRequest(server);
ローカルサーバーで確認
$ npm run serve
public
ディレクトリをアップするため、以下を実行
$ npm run init-deploy
次回以降は、public
ディレクトリをアップしないので、以下でOK
$ npm run deploy
コミットしてGitHubにプッシュ
$ git add .
$ git commit -m "コミットメッセージ"
$ git push origin HEAD
本番環境
firebaseで本番環境も対応する場合は切り替えが必要なので対応
コンソールで新規プロジェクト作成
今回は2種類の本番環境を用意
- 静的ホスティング
- 静的なサイトであれば十分
- Cloud Functions for Firebase を経由しないのでパフォーマンス的には少し有利?
- Expressをそのまま使用
- Node.jsが使える
- よって、ExpressじゃなくてもOK
- Node.jsが使える
環境構築(静的ホスティング)
develop
ブランチから新たにブランチを作成
$ git checkout -b static_hosting
作成した本番用プロジェクトのホスティング情報を.firebaserc
に追加
$ firebase target:apply hosting production <production-project-id>
$ firebase target:apply hosting staging <staging-project-id>
firebase.json
に環境別のホスティング情報を追記
{
"functions": {
"source": "functions",
"predeploy": "npm run preserve"
},
+ "hosting": [{
+ "target": "staging",
+ "public": "public",
+ "ignore": [
+ "firebase.json",
+ "**/.*",
+ "**/node_modules/**"
+ ],
+ "rewrites": [
+ {
+ "source": "**",
+ "function": "stagingApp"
+ }
+ ]
+ },
+ {
+ "target": "production",
+ "public": "functions/dist",
+ "ignore": [
+ "firebase.json",
+ "**/.*",
+ "**/node_modules/**"
+ ]
+ }]
}
package.json
の書き換え
"scripts": {
"build": "tsc --project functions",
"preserve": "npm run build && npm run copy-deps && npm run install-deps",
"serve": "npm run build && firebase serve",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy-init": "firebase deploy",
- "deploy": "firebase deploy --only functions",
+ "deploy-staging": "firebase deploy --only functions",
+ "deploy-production": "firebase deploy --only hosting:production",
"logs": "firebase functions:log",
"copy-deps": "cpx \"*{package.json,package-lock.json,yarn.lock}\" \"functions\" -C",
"install-deps": "cd functions && npm install && cd ../"
},
ステージングにデプロイ
$ npm run deploy-staging
本番にデプロイ
$ npm run deploy-production
環境構築(Express環境)
一度、develop
ブランチに戻り、express_hosting
ブランチを新たに作成
$ git checkout develop
$ git checkout -b express_hosting
作成した本番用プロジェクトを指定し、エイリアスを設定
$ firebase use --add
$ What alias do you want to use for this project? (e.g. staging)
.firebaserc
にプロジェクトが追加される(今回はproduction
というエイリアスで登録)
もともとのdefault
エイリアスはわかりやすい名前に変えてOK(以下はstaging
に変更)
{
"projects": {
- "default": "<staging-project-id>",
+ "staging": "<staging-project-id>",
+ "production": "<production-project-id>"
}
}
firebase.json
も変更
{
"functions": {
"source": "functions",
"predeploy": "npm run preserve"
},
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
- "function": "stagingApp"
+ "function": "app"
}
]
}
}
npm script
にプロジェクトの切り替えタスクを追加
"scripts": {
"build": "tsc --project functions",
"preserve": "npm run build && npm run copy-deps && npm run install-deps",
"serve": "npm run build && firebase serve",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"init-deploy": "firebase deploy",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log",
"copy-deps": "cpx \"*{package.json,package-lock.json,yarn.lock}\" \"functions\" -C",
"install-deps": "cd functions && npm install && cd ../",
+ "env-staging": "firebase use staging",
+ "env-production": "firebase use production"
}
プロジェクト切り替えが可能になる
$ npm run env-xxx
本番環境でベーシック認証解除
環境変数をクローンし、問題がないか確認
$ firebase functions:config:clone --from <project-id>
$ firebase functions:config:get
以下のディレクトリとファイルを作成
functions/src
└ app
├ app.ts
├ index.ts
├ productionApp.ts
└ stagingApp.ts
functions/src/app/stagingApp.ts
import * as functions from 'firebase-functions';
import * as express from 'express';
// 型定義ファイルを作るのが面倒なので妥協。。。
const basicAuth = require('basic-auth-connect');
const user = functions.config().basicauth.user;
const pass = functions.config().basicauth.pass;
const server = express();
server.use(basicAuth(user, pass));
server.use(express.static('./dist'));
export const stagingApp = functions.https.onRequest(server);
functions/src/app/productionApp.ts
import * as functions from 'firebase-functions';
import * as express from 'express';
const server = express();
server.use(express.static('./dist'));
export const productionApp = functions.https.onRequest(server);
functions/src/app/app.ts
import { productionApp } from './productionApp';
import { stagingApp } from './stagingApp';
const isStaging = process.env.GCLOUD_PROJECT === '<staging-project-id>';
export const app = isStaging ? stagingApp : productionApp;
functions/src/app/index.ts
export { app } from './app';
functions/src/index.ts
を書き換え
export { app } from './app';
本番環境用ローカルサーバーを立ち上げ
$ npm run env-production
$ npm run serve
テスト環境用ローカルサーバーを立ち上げ
$ npm run env-staging
$ npm run serve
本番環境にデプロイ
$ npm run env-production
$ npm run init-deploy
次回以降は、以下でOK
$ npm run env-production
$ npm run deploy
テスト環境にデプロイ
$ npm run env-production
$ npm run deploy
コミットしてGitHubにプッシュ
$ git add .
$ git commit -m "コミットメッセージ"
$ git push origin HEAD
最後にGitHubでプルリクエストを作り、develop
ブランチにマージしてみましょう!