クライアント側もサーバ側も徐々に準備が整って来たので、ここらでクラウド環境へデプロイできるようにしておきましょう。
今回はサーバ側をCloud Runで実行、クライアント側をFirebase Hostingで配信、という構成にしていきます。
※ 注意 ※
課金が発生する可能性があります。
下準備
GCPにプロジェクトを作成しておきます。
また、dockerも利用可能にしておいてください。
Firebase Hosting
まずFirebase CLIをインストールします。ログインもしておきましょう。
$ npm install -g firebase-tools
$ firebase login
次にFirebaseの設定ファイルを生成します。
$ cd /path/to/project/client
$ firebase init
firebase init
を実行するとウィザード形式で様々な質問をされます。
以下のように回答していきます。
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i>
to invert selection, and <enter> to proceed)
❯◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
のみを選択してEnter
? Please select an option: (Use arrow keys)
❯ Use an existing project
を選択
? Select a default Firebase project for this directory: (Use arrow keys)
❯ toitta-dev (toitta-dev)
を選択(自分の環境に合わせてください)
? What do you want to use as your public directory? (public)
dist を入力してEnter
? Configure as a single-page app (rewrite all urls to /index.html)? (y/N)
y を入力してEnter
? Set up automatic builds and deploys with GitHub? (y/N)
N を入力してEnter
? File dist/index.html already exists. Overwrite? (y/N)
N を入力してEnter
これで、下記のようなclient/.firebaserc
とclient/firebase.json
が生成されたはずです。
{
"projects": {
"default": "toitta-dev"
}
}
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
とりあえずデプロイしてみましょう。下記を実行します。
$ cd /path/to/project/client
$ npm run build
$ firebase deploy
firebase deploy
を実行すると進捗状況が表示され、最後に Hosting URL: https://toitta-dev.web.app
のようにURLが表示されると思いますのでアクセスしてみましょう。
APIが動作していないので挙動がおかしいですがいままで作成してきた画面が表示されたと思います。
Cloud Run
次はサーバー側をCloud Runで動かすようにしていきましょう。下記のチュートリアルが参考になります。
まずは、gunicornをインストールします。下記にも記載がありますが、flask run
を開発目的以外で利用するのは推奨されていません。
下記のように requirements.txt を修正します。
Flask
pymongo[srv]
gunicorn
いつものようにインストールとconstraints.txtの更新を行いましょう。
$ cd /path/to/project/server
$ pip install -r requirements.txt -c constraints.txt
$ pip freeze > constraints.txt
次に下記の Dockerfile
と .dockerignore
を作成します。
# Use the official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.10-slim
# Allow statements and log messages to immediately appear in the Knative logs
ENV PYTHONUNBUFFERED True
# TODO
ENV MONGO_CREDENTIAL admin:XXXXX
# Copy local code to the container image.
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
# Install production dependencies.
RUN pip install --no-cache-dir -r requirements.txt -c constraints.txt
# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
# Timeout is set to 0 to disable the timeouts of the workers to allow Cloud Run to handle instance scaling.
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
Dockerfile
README.md
*.pyc
*.pyo
*.pyd
__pycache__
.pytest_cache
server-env
これでdocker上で実行する準備ができました。実際にローカルのdocker上で動かしてみましょう。
$ cd /path/to/project/server
$ docker build --tag toitta:test .
$ docker run --rm -p 9090:8080 -e PORT=8080 toitta:test
これで立ち上がっているはずです。
リクエストを送ってみましょう。
$ curl -X POST -H "Content-Type: application/json" -d '{"identifier":"hoge", "password":"fuga"}' localhost:9090/api/login
{"_id":"622c82265313db38daf489aa","display_name":"hoge","email":"hoge@example.com","username":"hoge"}
無事 docker 上でも動かすことができました。(server/__init__.py
が悪さして最初は動かなかったので修正しました...)
それではこちらをCloud Run上で動作させてみましょう。
$ cd /path/to/project/server
(↓ toitta-dev の部分はGCPの自身のプロジェクト名に変更が必要)
$ gcloud builds submit --tag gcr.io/toitta-dev/toitta-api
$ gcloud run deploy toitta-api --image gcr.io/toitta-dev/toitta-api
API [run.googleapis.com] not enabled on project ...
などが表示されたら y を入力してください。
進捗が表示され、最後に Service URL: https://toitta-api-mehiivqyda-an.a.run.app
などが表示されると思うので、確認してみましょう。
$ curl -X POST -H "Content-Type: application/json" -d '{"identifier":"hoge", "password":"abc"}' https://toitta-api-mehiivqyda-an.a.run.app/api/login
{"_id":"622c82265313db38daf489aa","display_name":"hoge","email":"hoge@example.com","username":"hoge"}
うまくいきましたね!
Firebase Hosting と Cloud Run の連携
を参考に、/apiのリクエストをCloud Runに向けてあげましょう。firebase.jsonを修正します。
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/api/**",
"run": {
"serviceId": "toitta-api",
"region": "asia-northeast1"
}
},
{
"source": "**",
"destination": "/index.html"
}
]
}
}
再度画面をデプロイします
$ cd /path/to/project/client
$ firebase deploy
YES!! ちゃんとAPIも利用できていますね!
今回はここまでにしましょう。