Firebase Hosting と Cloud Run でサーバレスアプリを立ち上げる
Google Cloud のサービスを利用して、サーバレスアプリを立ち上げた時の手順です。
構成
- フロントエンド:Nuxt.js SPA
デプロイ先:firebase hosting - バックエンド:Python fastapi
デプロイ先:Cloud Run
Nuxt.js でビルドした静的ファイルを Firebase Hosting にデプロイ、Python を Cloud Run にデプロイし、REST API として立ち上げます。
以下の公式サイトを参考に行いました。
手順早見
- 前準備
- Google アカウントと GCP の準備
- プロジェクト生成
- 請求先の設定
- Clooud Run API の有効化
- Cloud SDK 導入
- バックエンド
- コードの記述
- コンテナの準備
- firebase hosting の URL を許可する。
- Cloud Run にデプロイ
- フロントエンド
- 環境構築
- Cloud Run の URL を記述
- nuxt.js プロジェクト作成
- Cloud Run との連携
- Firebase Hosting にデプロイ
- 環境構築
前準備
Google アカウントと GCP の準備
GCP を持っていない場合は、以下を参考に GCP の登録まで行ってください。
プロジェクト作成
Cloud Consoleへ移動し、プロジェクト名が表示されている部分をクリック
「新しいプロジェクト」を選択します
今回立ち上げる Web アプリのプロジェクトを作成します。
請求先の設定
作成したプロジェクトに移動し、「ナビゲーションメニュー」→「お支払い」→「請求先アカウント」→「請求先アカウントを管理」へ移動します。
請求先アカウントが無ければ作成します。
作成した請求先アカウントをプロジェクトに紐づけ
Cloud Run を使用するために、プロジェクトと請求先アカウントが紐付いているか確認します。
私の場合は、下記のように請求先アカウントが紐付いた状態になっていました。
Clooud Run API の有効化
cloud-sdk 導入
Cloud-SDK とは GCP 用の CLI です。
GCP 上のコンソールからでも使えるのですが、今回はローカルにインストールしました。
下記のコマンドで Cloud SDK をインストールします。
#Cloud SDK の配布 URI をパッケージ ソースとして追加
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
#apt-transport-https がインストールされていることを確認
sudo apt-get install apt-transport-https ca-certificates gnupg
#Google Cloud の公開鍵をインポート
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
#Cloud SDK を更新してインストール
sudo apt-get update && sudo apt-get install google-cloud-sdk
プロジェクトの準備
下記の構成でプロジェクトディレクトリを作成します。
sample-project/
└frontend/
└backend/
# 適当な階層で実行
mkdir sample-project
cd sample-project
mkdir frontend
mkdir backend
プロジェクト設定
下記は今回のプロジェクトで使う設定です。
以降の説明では変数値で説明しますので、
自身の環境に応じて書き換えてください。
変数名 | 変数値 |
---|---|
project_id | sample-project-33 |
フロントエンド service_id | front-app |
バックエンド service_id | backend-app |
firebase ホスティング URL | https://sample-project.web.app |
cloud run URL | https://backend-app-vbppox-an.a.run.app |
Cloud Run の有効化
Cloud Run API ページでプロジェクトを選択し、API を有効にします
バックエンド
コードの記述
backend 直下に main.py を下記の内容で作成。
from fastapi import FastAPI
app = FastAPI()
# CORSのエラーを避けるために、originsにfirebase hostingのURLを追加しておく。
origins = [
{Firebase-hosting_URL},
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
def read_root():
return {"hello": "world"}
origins の Firebase-hosting_URL は後述します。
コンテナの準備
Dockerfile を準備します。
FROM python:3.9-slim
# Allow statements and log messages to immediately appear in the Knative logs
ENV PYTHONUNBUFFERED True
# Copy local code to the container image.
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
# Install production dependencies.
RUN pip install fastapi uvicorn
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port","8080"]
fastapi 立ち上げに最低限必要なものに絞っています
GCP プロジェクトとの紐づけ
gcloud コマンドを使用して GCP のプロジェクトと、ローカルのプロジェクトを紐づけます
$ gcloud init
# 新規プロジェクトを作成
Pick configuration to use:2 Create a new configuration
#ローカルのプロジェクト名を入力
Enter configuration name. Names start with a lower case letter and
contain only lower case letters a-z, digits 0-9, and hyphens '-':sample-project
#使用するGoogleアカウントを選択
Choose the account you would like to use to perform operations for
this configuration:1 xxx@gmail.com
#GCP上の紐付けるプロジェクトを選択
Pick cloud project to use:sample-project-33
Cloud Run にデプロイ
これで cloud Run にデプロイする準備が整いました。
backend ディレクトリに移動して、下記コマンドでコンテナをビルドしてみます。
gcloud builds submit --tag gcr.io/sample-project-33/backend-app
ビルドが完了すると、Container Registry に、バックエンドのイメージがアップロードされている事が確認出来ます。
続いて Cloud Run へデプロイを行います
# イメージを選択し、Cloud Runへデプロイする
$ gcloud run deploy --image gcr.io/sample-project-33/backend-app
#サービス名の入力
Service name (backend-app):Enter
#リージョンの選択
Please specify a region:
Please enter your numeric choice:3 asia-northeast1
#未認証の呼び出しを許可
Allow unauthenticated invocations to [eventsearch] (y/N)? y
成功すると、Deploy 結果が表示されます。
Service URL にアクセスしてみてください。
✓ Deploying... Done.
✓ Creating Revision...
✓ Routing traffic...
✓ Setting IAM Policy...
Done.
Service [backend-app] revision [backend-app-00006-nil] has been deployed and is serving 100 percent of traffic.
Service URL: https://backend-app-vbppox-an.a.run.app
ブラウザで「hello-world!」と表示されれば成功です。
{Service URL}/docs と打つと、Swaggar UI が立ち上がっていることも確認できます。
これでバックエンド側は完成です。
またデプロイコマンドの選択は、引数で一括指定することも出来ます
gcloud run deploy backend-app --image gcr.io/sample-project-33/backend-app --region asia-northeast1 --allow-unauthenticated
GCP コンソールの Cloud Run を開くと、動作しているサービスを確認出来ます。
フロントエンド
続いてフロントエンド側を作成します。
環境構築
node, yarn, firebase-tools をインストールします。
sudo apt install -y nodejs npm
# npm 経由でyarnをインストール
sudo npm install -g yarn
yarn global add firebase-tools
フロントエンドの手順は docker で作成しても問題ありません。
docker で構築したコードは github で公開しています。
nuxt.js プロジェクト作成
nuxt-app 作成
yarn create nuxt-app
nuxt-app 作成時の選択は下記にしました。
create-nuxt-app v3.7.1
✨ Generating Nuxt.js project in .
? Project name: frontend-app
? Programming language: TypeScript
? Package manager: Yarn
? UI framework: Bootstrap Vue
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: ESLint, Prettier
? Testing framework: None
? Rendering mode: Single Page App
? Deployment target: Static (Static/Jamstack hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: None
? Version control system: None
プロジェクトを作成し終わったら、早速実行してみます
yarn dev
指定された URL(localhost:3000?)にアクセスし、下記が表示されたらプロジェクトの初期化完了です。
Cloud Run(バックエンド)との連携
axios で cloud run へ接続するコードを書きます
index.vue
<template>
<div class="container">
<button @click="getHello()">connect cloud run</button>
<p>{{ posts }}</p>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import axios from "axios";
export default Vue.extend({
data() {
return {
posts: "",
};
},
methods: {
async getHello() {
const response = await axios.get(
"https://backend-app-vbppox-an.a.run.app/"
);
this.posts = response.data;
},
},
});
</script>
完成したら再度します
yarn dev
ブラウザで下記の画面が表示されたら、"connect cloud run"を押して、cloud run との接続を確認します。
画像のように{"hello":"world"}と表示されたらフロントエンドの完成です。
Firebase Hosting にデプロイ
続いて firebase と連携します。
firebase init hosting
? Allow Firebase to collect CLI usage and error reporting information? Yes
i To change your data collection preference at any time, run `firebase logout` and log in again.
=== Project Setup
? Please select an option: Add Firebase to an existing Google Cloud Platform project
? Select the Google Cloud Platform project you would like to add Firebase: sample-project-33 (sample-project)
=== 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? dist
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? Set up automatic builds and deploys with GitHub? No
✔ Wrote dist/index.html
i Writing configuration info to firebase.json...
i Writing project information to .firebaserc...
✔ Firebase initialization complete!
ブラウザに firebase へ連携する画面が表示されます。
連携するアカウントを選択し、OK を押す。
successfull
Visit this URL on this device to log in:
https://accounts.google.com/o/oauth2/auth?client_id=563584335869-fgrhgmd47bqnekij5i8b5pr03ho849e6.apps.googleusercontent.com&scope=email%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloudplatformprojects.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Ffirebase%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&response_type=code&state=1009920591&redirect_uri=http%3A%2F%2Flocalhost%3A9005
Waiting for authentication...
✔ Success! Logged in as {googleアカウント}
作成したプロジェクトを firebase hosting にデプロイします
yarn build
yarn generate
firebase deploy
Deploy complete!と出たら完成です。
表示されている Hosting URL にアクセスしてみてください
Deploy complete!
Project Console: https://console.firebase.google.com/project/sample-project-33/overview
Hosting URL: https://sample-project-33.web.app
Done in 102.11s.
この段階では、CORS エラーにより cloud run へアクセスできません。
バックエンドの main.py, origins に Hosting URL を追加します
origins = [
"https://sample-project-33.web.app",
]
改めて gcloud へ[ビルド&デプロイ](#Cloud Run にデプロイ)を行います。
完了後、Hosting URL にアクセスし、"connect cloud run"ボタン押下で Hello world が出たら
firebase hosting と cloud run の連携が完成です。
最終的なディレクトリ構成
sample-project/
└frontend/
└
└backend/
└main.py
└Dockerfile
└firebase.json
-dist
└その他nuxt.js関連のファイル・ディレクトリ多数
今回はここで終了です。
使用したコード
使用したコードは github に載せています。
- frontend
- backend
引き続き CI/CD 編 を書きます。
記事予告:cloud run と firebase hosting の CI/CD 環境を構築する。
Discussion