1
/
5

Cloud Run + django + Cloud Sql のデプロイ

前提

とくにCloud Runを初めて使う人、使ってみてるけどうまくいかない人向けです。

ローカル環境について

  • Pythonのバージョン: 3.10.0
  • Dockerのバージョン: 20.10.8
  • DB(postgres)のバージョン: 14.0

この記事で説明しないこと:

  • Cloud Sql, Cloud Runの説明

準備するもの

  • Cloud Sqlのインスタンスが作成されている
  • Djangoのプロジェクト(ソース)が手元にある
  • gcloudコマンドがインストールされている
  • gcpのコンソールにログインできる

手順

手順としては、3ステップで説明する。

  • デプロイのための準備
  • dockerイメージをリポジトリに登録する
  • Cloud Runにアプリ(django)をデプロイする

デプロイのための準備

環境変数を設定する

に読み込むようにします。Cloud Runで実行するには都合を考えて、djangoにおけるDBの接続情報などを環境変数を.env
ファイルから読み込むようにしておきます。
今回はenviron
を利用して、.env
からsettings.py

pip install django-environ

settings.py

import os
import environ

env = environ.Env()
env.read_env('.env')

SECRET_KEY = env('SECRET_KEY')
DEBUG = env.get_value('DEBUG',bool)
DATABASES = {
## DATABASE_URLとして読み込まれる
'default': env.db()
}

.env

DATABASE_URL=postgres://postgres:postgres@db:5432/postgres
SECRET_KEY=<SECRET_KEY>
DEBUG=True

注意すること

  • DEBUG=Falseにならないboolean型として判定させるためには、キャストするようにsettings.pyに記入する必要がある

の設定値を文字列(String)として読み込みます。環境変数にboolean
型を入れるときは、get_value
の第2引数にboolを指定する必要があります。
というのも、環境変数はenviron
を使って.env

settings.py(一部)

DEBUG = env.get_value('DEBUG',bool)

.env(一部)

DEBUG=True

DBを作成、マイグレーションする

に接続するインスタンスは作成している前提として、そこに作ったDBを作ります。Cloud Run
にデプロイするアプリ(django)からCloud Sql

Cloud SqlのDBの作り方はここでは割愛します。

次にローカルの開発環境からDBへマイグレーションを行います。

  • ローカルでのアーキテクチャ

という名前でサービスを設定します。cloud proxyを利用してローカル環境からデータベースに接続するために、docker-compose.ymlにcloud proxyのサービスを設定します。今回はcloudsql-proxy

docker-compose.yml(一部抜粋)

version: '3'

services:
## cloudsql-proxyというサービスを追加する
cloudsql-proxy:
image: gcr.io/cloudsql-docker/gce-proxy:1.19.1
volumes:
- ./<service-account>.json:/config/key.json
ports:
- "5432:5432"
environment:
TZ: Asia/Tokyo
restart: always
command: /cloud_sql_proxy -instances="<cloud-sql-connection>"=tcp:0.0.0.0:5432 -credential_file=/config/key.json

のサービスをスタートします。cloudsql-proxy

docker-compose up cloudsql-proxy

という名前でDockerのネットワークにおけるDNSの解決ができるようになります。こうするとcloudsql-proxy

.env(一部抜粋)

## cloudsql-proxyという名前で、5432番ポートを使って接続します
DATABASE_URL=postgres://<cloud-sql-db-user-name>:<cloud-sql-db-password>@cloudsql-proxy:5432/<db-name>

最後にdjangoのマイグレーションコマンドを実行します。

djangoのマイグレーション

python manage.py migrate

うまくいくとCloud SqlのDBに接続しながら、ローカルのdjangoアプリをブラウザで動作を確認することができます。

注意すべきこと

サービスアカウントにCloud SqlのIAMを付与する

GCPにおけるリソースはIAMで管理されます。今回使うCloud Runでは実行するサービスアカウントを指定することができます。その指定するサービスアカウントにはCloud Runを実行するロールを持ったサービスアカウントを指定する必要があります。



IAMからサービスアカウントにロールが付与されているかを確認します。

データベースの接続名は108文字以内にする

です。Unixのソケット通信が108文字までしか対応してないらしいです。gcpの公式にも注意があります。Cloud Runで実行されるWEBアプリ(今回はdjango)は、Cloud Sql上のDBにUnixソケットを使って接続します。
ここで気をつけるのは接続名を108以内にすること

Cloud Sqlの起動時間が長い

Cloud Sqlのインスタンスを起動しようとすると、ぼくの場合だけかもしれないですが5分-8分くらいかかります。

作業をスムーズに進めたいときには、先にCloud Sqlのインスタンスをスタートしておくとかの対応をすると良いと思います。

Cloud Sqlの費用に気をつける

パブリッククラウドにおけるDBのサービスは、どこでもだいたい高くなりがちです。gcpもその例に漏れません。何も考えずにデフォルトのプランでインスタンス立ち上げっぱなしにすると、請求日にびっくりするような料金が請求されることになります。

Cloud Sqlのインスタンスの設定にはくれぐれも気をつけるようにしましょう。


↑これが最安のインスタンスの設定になります(多分。)

dockerイメージをリポジトリに登録する

  • Artifact RegistoryかContainer RegistoryにDockerイメージをpushする

Cloud Runでアプリを実行するときには、Cloud Runが実行するコンテナ上でwebアプリを実行します。そのコンテナ上で実行されるWEBアプリのコンテナイメージを予めgcpのイメージレジストリに登録しておく必要があります。
コンテナイメージを保存するのは、Artifact RegistoryでもContainer RegistoryでもOKです。

を指定します。ステージングのとしてビルドしたい場合は、DockerfileをDockerfile.staging
のような名前でDockerfile作成し、docker-compose.staging.yml
でDockerfile.staging

Dockerfile.staging

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
ADD . /code/
EXPOSE 8000
CMD python3 manage.py migrate
CMD python3 manage.py runserver 0.0.0.0:$PORT

でポート番号をしていして、実行することができます。
そのためのDokcerfileに引数が取れるように指定しておきます。$PORT
としておくと、Cloud Run
で実行するときにCloud Run

docker-composeコマンドでbuildする

docker-compose -f docker-compose.staging.yml build
docker push us-central1-docker.pkg.dev/<artifact-registory-path>:latest

Cloud RunのGUIからアプリ(django)をデプロイする

ここでやることは大きく3つあります。↓

  • 環境変数をCloud Runから読み込むようにする
  • Cloud SQLの接続情報を環境変数から読み込む
  • コンテナポートは8000にする

キャプチャとともに説明していきます。

を押下する1.新しいリビジョンの編集とデプロイ


2. コンテナのイメージに予めpushしておいたコンテナのイメージを選択する


に予めpushしておいたコンテナのイメージを指定します。今回の場合はdjangoアプリのイメージを選択します。コンテナイメージのURL

=8000にします。リッスンするコンテナのポートをコンテナポート

にポート番号指定無しでアクセスすると、内部的にコンテナの8000番ポートにリクエストが転送されます。デプロイがうまくいったときに生成されるURL、https://<hogehoge>-uc.a.run.app

を設定する3.メモリ
、CPU


を適当に設定します。
1コンテナに仮想的に割り当てられるリソースは少なめにしておいたほうがお安く済むと思います。(多分)コンテナに割り当てるメモリ
、CPU

も設定します。併せて、自動スケーリング

については適当でいいです。自動スケーリングが必要になるタイミングが今回はあまりないと思うので。自動スケーリングのインスタンスの最小数
を1
に、インスタンスの最大数

割り当てるリソースが少ないほど、お安く済むと思います。(多分)

4. 環境変数をセットする


からセットします。.env
で指定するパラメータをCloud Runにデプロイするときには、変数とシークレット

を指定します。(↓画像参照)DATABASE_URL
にはCloud SQLの接続名


を指定しています。またSECRET_KEY
はdjangoのsettings.py
にあるSECRET_KEY

5. Cloud SQLの接続する


に、予め作成しておいたインスタンスを指定します。Cloud SQL接続

6. サービスアカウントを指定する


をコントロールするロールが付与されておく必要があります。サービスアカウント
として、先程設定したサービスアカウントを指定します。
このときサービスアカウント
にCloud SQL

を押下すると、デプロイが開始されます。これでCloud Run
に設定することは以上です。後はページ下部のデプロイ

Cloud Runを使うときに注意すべきこと

を使うときに注意すべき点を説明しておきます。Cloud Run

Cloud SQLを実行するIAMが必要

を実行するだけのIAMをサービスアカウントに付与しておく必要があります。今回は以下のロールが必要になります。Cloud Run

Cloud Run 起動元
Cloud SQL クライアント
メディア バケットの Storage 管理者
Django 設定シークレットの Secret Manager Accessor。(Django 管理シークレットへのアクセスは、サービス自体には必要ありません。)

まとめ

でのデプロイができるはずです。以上の手順でCloud Run + Cloud SQL + django


さいごに

このwantedlyストーリーは、カラビナテクノロジー株式会社のサーバーサイドエンジニア「bravo」が書いたZennから転載をしております。

合わせてbravoのZennもよろしくお願いします。


カラビナテクノロジー株式会社's job postings

Weekly ranking

Show other rankings
If this story triggered your interest, go ahead and visit them to learn more