環境
MacOS Ventura
Python 3.10.7
Poetry 1.3.2
はじめに
この記事はこちらの続きです
https://qiita.com/ps0317ix/items/ff10e0eddfc24e5db96c
早速始めよう
正直Googleの公式がかなり充実してるのでこれで問題ないですが、あえて噛み砕いて手順を説明します
https://cloud.google.com/python/django/run?hl=ja
必要なライブラリを追加
poetry add psycopg2-binary gunicorn django-environ django-storages google-cloud-secret-manager
あとは公式ドキュメントに沿っていきます。
1. API の認証情報を取得して認証
gcloud auth application-default login
2. Cloud SQL Auth プロキシをダウンロードしてローカルマシンにインストール
curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.arm64
chmod +x cloud_sql_proxy
3. PostgreSQL インスタンスを作成
以下に置き換えてください
INSTANCE_NAME: Cloud SQL インスタンス名
PROJECT_ID: Google Cloud プロジェクト ID
REGION: Google Cloud リージョン
gcloud sql instances create INSTANCE_NAME \
--project PROJECT_ID \
--database-version POSTGRES_13 \
--tier db-f1-micro \
--region REGION
作成したインスタンス内に、データベースを作成
gcloud sql databases create DATABASE_NAME \
--instance INSTANCE_NAME
データベース ユーザーを作成
gcloud sql users create DATABASE_USERNAME \
--instance INSTANCE_NAME \
--password DATABASE_PASSWORD
4. Cloud Storage バケットを設定
gsutil mb -l REGION gs://PROJECT_ID_MEDIA_BUCKET
5. Secret Manager シークレットとして Django 環境ファイルを作成
echo DATABASE_URL=postgres://DATABASE_USERNAME:DATABASE_PASSWORD@//cloudsql/PROJECT_ID:REGION:INSTANCE_NAME/DATABASE_NAME > .env
echo GS_BUCKET_NAME=PROJECT_ID_MEDIA_BUCKET >> .env
echo SECRET_KEY=$(cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]'| fold -w 50 | head -n1) >> .env
echo PROJECTNUM=$(gcloud projects describe PROJECT_ID --format='value(projectNumber)') >> .env
6. シークレットをSecret Managerに保存
gcloud secrets create django_settings --data-file .env
7. 動作確認
settings.pyに以下を追加していきます
import io
import os
import environ
from pathlib import Path
from datetime import timedelta
import google.auth
from google.cloud import secretmanager
from google.oauth2 import service_account
from datetime import timedelta
from pathlib import Path
from storages.backends.gcloud import GoogleCloudStorage
env = environ.Env(DEBUG=(bool, True))
env_file = os.path.join(BASE_DIR, ".env")
try:
_, os.environ["GOOGLE_CLOUD_PROJECT"] = google.auth.default()
except google.auth.exceptions.DefaultCredentialsError:
pass
if os.path.isfile(env_file):
print('Use a local secret file, if provided')
env.read_env(env_file)
service_account_json = get_or_create_service_account_json(BASE_DIR)
credentials = service_account.Credentials.from_service_account_info(service_account_json)
elif os.environ.get("GOOGLE_CLOUD_PROJECT", None):
print('Pull secrets from Secret Manager')
project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
client = secretmanager.SecretManagerServiceClient()
settings_name = os.environ.get("SETTINGS_NAME", "django_settings")
name = f"projects/{project_id}/secrets/{settings_name}/versions/latest"
payload = client.access_secret_version(name=name).payload.data.decode("UTF-8")
env.read_env(io.StringIO(payload))
elif os.getenv("TRAMPOLINE_CI", False):
print('Create local settings if running with CI, for unit testing')
placeholder = (
f"SECRET_KEY=a\n"
"GS_BUCKET_NAME=None\n"
f"DATABASE_URL=sqlite://{os.path.join(BASE_DIR, 'db.sqlite3')}"
)
env.read_env(io.StringIO(placeholder))
service_account_json = get_or_create_service_account_json(BASE_DIR)
credentials = service_account.Credentials.from_service_account_info(service_account_json)
else:
raise Exception("No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.")
SECRET_KEY = os.getenv('SECRET_KEY')
DJANGO_NINJA_TEMPLETEにutils.pyを追加
import json
import os
from google.cloud import secretmanager
def get_service_account_json():
project_num = os.environ.get("PROJECTNUM")
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_num}/secrets/service_account/versions/latest"
response = client.access_secret_version(name=name)
secret_string = response.payload.data.decode("UTF-8")
return json.loads(secret_string)
def get_service_account_json_from_file(json_file_path):
with open(json_file_path, "r") as json_file:
return json.load(json_file)
def store_service_account_json_to_file(json_data, json_file_path):
with open(json_file_path, "w") as json_file:
json.dump(json_data, json_file)
def get_or_create_service_account_json(base_dir):
json_file_path = os.path.join(base_dir, "static", "service_account.json")
if os.path.isfile(json_file_path):
return get_service_account_json_from_file(json_file_path)
json_data = get_service_account_json()
store_service_account_json_to_file(json_data, json_file_path)
return json_data
GCPでサービスアカウントを作成し、シークレットキーを作成します
https://cloud.google.com/iam/docs/creating-managing-service-account-keys?hl=ja
Secret Managerを開き、『service_account』という名のシークレットを作成し、上記で作成したJSONの内容を追加してください。
https://console.cloud.google.com/security/secret-manager
Cloud Proxyを起動
./cloud_sql_proxy -instances="PROJECT_ID:REGION:INSTANCE_NAME"=tcp:5432
次にstaticというフォルダを作成し、以下のコマンドを実行し、Djangoを起動します
python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic
python manage.py runserver
立ち上がれば一旦OK!!