📖

Flask APIをGoogle Cloud Runへデプロイする

2022/03/05に公開

What is this?

「Slack slashコマンドから、Google Reminderを設定する」の後編です。前編ではFlaskを用いたAPI開発を行いました。後編では、開発したAPIをコンテナごとGoogle Cloud Runへデプロイします。

Google Cloud Runとは

公式ページからの引用によると、

Cloud Run は、マシンのプロビジョニング、クラスタの構成、自動スケーリングについて心配することなく、サーバーレス HTTP コンテナをデプロイしてスケールするためのフルマネージド コンピューティング環境です。

つまり、「コンテナごとアプリケーションを乗っけると、フルマネージドなサーバーレスサービスの上で動かしてくれる」「コンテナごとデプロイするので、Cloud Functions等と比べて言語・ランタイムの制約が少ない」と理解しています。

実行環境

  • HP Elite c1030 Chromebook
    • Debian 10.11

準備

Cloud SDKのインストール

$ sudo gcloud components update

上記を実行すると、下記のように怒られるので言われるがままに従います。

ERROR: (gcloud.components.update) 
You cannot perform this action because the Google Cloud CLI component manager 
is disabled for this installation. You can run the following command 
to achieve the same result for this installation: 

sudo apt-get update && sudo apt-get --only-upgrade install google-cloud-sdk-datalab google-cloud-sdk-kpt google-cloud-sdk-app-engine-java google-cloud-sdk-nomos google-cloud-sdk-cbt google-cloud-sdk-app-engine-python google-cloud-sdk-pubsub-emulator google-cloud-sdk-firestore-emulator google-cloud-sdk-gke-gcloud-auth-plugin kubectl google-cloud-sdk-datastore-emulator google-cloud-sdk-app-engine-grpc google-cloud-sdk google-cloud-sdk-local-extract google-cloud-sdk-skaffold google-cloud-sdk-cloud-build-local google-cloud-sdk-app-engine-go google-cloud-sdk-bigtable-emulator google-cloud-sdk-terraform-validator google-cloud-sdk-config-connector google-cloud-sdk-kubectl-oidc google-cloud-sdk-app-engine-python-extras google-cloud-sdk-minikube google-cloud-sdk-cloud-run-proxy google-cloud-sdk-spanner-emulator google-cloud-sdk-anthos-auth

GCP上での準備

  • プロジェクト作成
  • 各種APIの有効化(Cloud Build・Cloud Run)

デフォルトのプロジェクトとリージョンの設定

2022/03/05現在ではus-central1以外のリージョンでも使用できそうですが、特に変える理由もないのでそのまま設定しています。

projectnameは準備したプロジェクト名称に合わせてください。

$ gcloud config set project projectname
$ gcloud config set run/region us-central1

Googleアカウントの認証

$ gcloud auth login

上記を実行すると、ブラウザが立ち上げるので、アカウントを認証します。

コンテナのビルド

まずはローカルでビルドと実行を確認

前編で開発したコンテナをまずはローカルでビルドします。

imagenameは好きな名称に書き換えてください。

$ docker build -t imagename

https://stackoverflow.com/questions/63782456/docker-compose-yml-in-google-cloud-run

ビルドが完了したら、ローカルで実行してみます。
ここで、Cloud Runのデフォルトポートは8080であるため、明示的に環境変数で指定します。[1]

$ PORT=8080 && docker run -it imagename

Cloud Buildでのコンテナビルド

Cloud Runにて参照するために、同じくGCP上のCloud Buildにてコンテナをビルドします。

$ gcloud builds submit --project projectname --tag gcr.io/projectname/applicationname

applicationnameは自由に設定できます。

ビルドは数分間かかり、最後にDONEと表示されれば完了です。

原因不明のビルドエラー

理由は全くわからないのですが、作業をしている中で、下記のようなエラーに出会いました。

build step 0 "gcr.io/cloud-builders/docker" failed: step exited with non-zero status: 1

調べても、直接的な原因はわからず。色々試している中で、コマンドを実行しているディレクトリに.gitが含まれていると、このエラーが発生することだけがわかりました。
.dockerignoreで除外指定をしても効果はありませんでした。

Cloud Runへのデプロイ

上記でビルドしたコンテナをCloud Runへデプロイします。

$ gcloud run deploy applicationname --project projectname --platform managed --source .

以前は、Cloud Run用の設定ファイルを用意する必要が合ったようなのですが、--source .を追加することで、そのあたりの設定を良しなに完了してくれるようです。

エラー処理

デプロイになにか異常があったときに、下記のようなエラーがでます。

Deployment failed                                                                                               
ERROR: (gcloud.beta.run.deploy) Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information.

「ポートが空いていないから、コンテナを起動できないよ」とエラー文では言っているのですが、どうやらコンテナ内でどのようなエラーが起こっても、このエラー文が返る仕様になっているようです。
エラーの詳細は、Cloud Runのログを見に行くと、Warning以外の項目にしれっとでていたりします。ただ、毎回確認するのも面倒なので、まずはローカルでしっかり起動できることを確認するのをおすすめします。

ちなみに、上記エラー分を信じて環境変数などを色々いじっている中で、下記エラー文への変化はありましが、根本的解決にはなりませんでした。

Deployment failed
ERROR: (gcloud.beta.run.deploy) Deploying Revision.

最後に、Slashコマンドとの結合

デプロイしたAPIサーバーのURLを確認

無事にデプロイが完了したら、APIサーバーのURLを確認します。
Cloud Runのコンソールから確認できます。

Slackアプリの設定

Slashコマンドの設定に、上記のURL+APIのメソッドを指定します。今回はgoremindというメソッドになるため、[URL]/goremindをRequest URLへ設定します。

以上で、一連のAPI開発とCloud Runへのデプロイとなります!Cloud Runは始めて使用しましたが、サーバーレスの手軽さとコンテナ開発での自由さが両立できて良い感じですね。

参考文献

https://qiita.com/massie_g/items/5a9ce514eaa7c460b5e3
https://qiita.com/sakas1231/items/423cd7efcce77f5e426a

脚注
  1. コード内で環境変数を読み取っています。 ↩︎

Discussion