DjangoをCloud Runにデプロイした時のメモ。
以下の記事を参考にしました。
Cloud Run での Django | Google Codelabs
今回はSQLiteを使用しているためCloud SQLは除外しています。
また、SQLiteは別で設定予定のため今回の作業には含まれません。
Cloud API を有効化
gcloud services enable \ run.googleapis.com \ cloudbuild.googleapis.com \ secretmanager.googleapis.com \ artifactregistry.googleapis.com
環境変数を設定
export PROJECT_ID=$(gcloud config get-value core/project) export REGION=us-central1
サービスアカウントを作成
gcloud iam service-accounts create cloudrun-sa export SERVICE_ACCOUNT=$(gcloud iam service-accounts list \ --filter cloudrun-sa --format "value(email)")
Artifact Registry を作成
export ARTIFACT_REGISTRY={$REGION}-docker.pkg.dev/{$PROJECT_ID}/containers
Storage バケットを作成
export GS_BUCKET_NAME={$PROJECT_ID}-media gcloud storage buckets create gs://{$GS_BUCKET_NAME} --location {$REGION}
バケットを管理する権限をサービスアカウントに付与する。
gcloud storage buckets add-iam-policy-binding gs://{$GS_BUCKET_NAME} \ --member serviceAccount:{$SERVICE_ACCOUNT} \ --role roles/storage.admin
Secret Managerに保存
echo GS_BUCKET_NAME=\"{$GS_BUCKET_NAME}\" >> .env echo SECRET_KEY=\"$(cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 50 | head -n 1)\" >> .env echo DEBUG=True >> .env
gcloud secrets create application_settings --data-file .env
サービス アカウントにこのシークレットへのアクセスを許可する。
gcloud secrets add-iam-policy-binding application_settings \ --member serviceAccount:{$SERVICE_ACCOUNT} --role roles/secretmanager.secretAccessor
作成されたことを確認。
gcloud secrets versions list application_settings
rm .env
設定ファイルを作成
記事を参考に設定ファイルを作成します。
mv myproject/settings.py myproject/basesettings.py touch myproject/settings.py
myproject/settings.py
import io import os from urllib.parse import urlparse import environ # Import the original settings from each template from .basesettings import * # Load the settings from the environment variable env = environ.Env() env.read_env(io.StringIO(os.environ.get("APPLICATION_SETTINGS", None))) # Setting this value from django-environ SECRET_KEY = env("SECRET_KEY") # Ensure myproject is added to the installed applications if "myproject" not in INSTALLED_APPS: INSTALLED_APPS.append("myproject") # If defined, add service URLs to Django security settings CLOUDRUN_SERVICE_URLS = env("CLOUDRUN_SERVICE_URLS", default=None) if CLOUDRUN_SERVICE_URLS: CSRF_TRUSTED_ORIGINS = env("CLOUDRUN_SERVICE_URLS").split(",") # Remove the scheme from URLs for ALLOWED_HOSTS ALLOWED_HOSTS = [urlparse(url).netloc for url in CSRF_TRUSTED_ORIGINS] else: ALLOWED_HOSTS = ["*"] # Default false. True allows default landing pages to be visible DEBUG = env("DEBUG", default=False) # Set this value from django-environ DATABASES = {"default": env.db("DATABASE_URL", default="sqlite:///db.sqlite3")} # Define static storage via django-storages[google] GS_BUCKET_NAME = env("GS_BUCKET_NAME") STATICFILES_DIRS = [] GS_DEFAULT_ACL = "publicRead" STORAGES = { "default": { "BACKEND": "storages.backends.gcloud.GoogleCloudStorage", }, "staticfiles": { "BACKEND": "storages.backends.gcloud.GoogleCloudStorage", }, }
requirements.txt(追加)
gunicorn django-storages[google] django-environ
Procfileを作成
touch Procfile
Procfile
web: gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 myproject.wsgi:application
イメージをビルドする
gcloud builds submit --pack image={$ARTIFACT_REGISTRY}/myimage
イメージ名は適宜変更します。
Cloud Runにデプロイ
gcloud run deploy django-cloudrun \ --region $REGION \ --image {$ARTIFACT_REGISTRY}/myimage \ --set-secrets APPLICATION_SETTINGS=application_settings:latest \ --service-account $SERVICE_ACCOUNT \ --allow-unauthenticated
デプロイが完了して表示されたURLを選択するとDjangoのスタートページが表示されます。
変更の適用
変更があった場合は、以下の操作を行います。
- 新しいイメージをビルド
- Cloud Run を更新
gcloud builds submit --pack image=${ARTIFACT_REGISTRY}/myimage
gcloud run services update django-cloudrun \ --region $REGION \ --image ${ARTIFACT_REGISTRY}/myimage
.envを読み込み
ローカル環境で開発する時は、環境変数を.env
から読み込めるほうが都合がいい場合もあったのでmyproject/settings.py
に以下を追加しました。
from pathlib import Path # プロジェクトのルートディレクトリを取得 BASE_DIR = Path(__file__).resolve().parent.parent # .envファイルを読み込む env_path = os.path.join(BASE_DIR, '.env') if Path(env_path).is_file(): env.read_env(env_path)