Django CMS ב-Cloud Run

1. מבוא

89eb4723767d4525.png

Cloud Run היא פלטפורמת מחשוב מנוהלת שמאפשרת להריץ קונטיינרים ללא שמירת מצב שאפשר להפעיל באמצעות בקשות HTTP. ‫Cloud Run הוא שירות ללא שרת: הוא מסתיר את כל ניהול התשתית, כך שאתם יכולים להתמקד במה שהכי חשוב – יצירת אפליקציות מעולות.

בנוסף, הוא משתלב באופן טבעי עם חלקים רבים אחרים במערכת האקולוגית של Google Cloud, כולל Cloud SQL למסדי נתונים מנוהלים, Cloud Storage לאחסון אובייקטים מאוחד ו-Secret Manager לניהול סודות.

Django CMS היא מערכת לניהול תוכן (CMS) ברמת הארגון, שמבוססת על Django. ‫Django הוא פלטפורמת אינטרנט ברמה גבוהה של Python.

במדריך הזה נשתמש ברכיבים האלה כדי לפרוס פרויקט קטן של Django CMS.

הערה: בדיקה אחרונה של ה-codelab הזה בוצעה עם Django CMS 4.1.2 באמצעות django-cms/cms-template v4.1.

מה תלמדו

  • איך משתמשים ב-Cloud Shell
  • איך יוצרים מסד נתונים ב-Cloud SQL
  • איך יוצרים קטגוריה של Cloud Storage
  • איך יוצרים סודות ב-Secret Manager
  • איך משתמשים בסודות משירותים שונים של Google Cloud
  • איך מחברים רכיבי Google Cloud לשירות Cloud Run
  • איך משתמשים ב-Container Registry לאחסון קונטיינרים שנבנו
  • איך פורסים ל-Cloud Run
  • איך מריצים מיגרציות של סכימות של מסדי נתונים ב-Cloud Build

2. הגדרה ודרישות

הגדרת סביבה בקצב אישי

  1. נכנסים ל-Google Cloud Console ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • שם הפרויקט הוא השם המוצג של המשתתפים בפרויקט הזה. זו מחרוזת תווים שלא נמצאת בשימוש ב-Google APIs. תמיד אפשר לעדכן את המיקום.
  • מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud, והוא קבוע (אי אפשר לשנות אותו אחרי שהוא מוגדר). מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית, ובדרך כלל לא צריך לדעת מה היא. ברוב ה-Codelabs, תצטרכו להפנות למזהה הפרויקט (בדרך כלל מסומן כ-PROJECT_ID). אם אתם לא אוהבים את המזהה שנוצר, אתם יכולים ליצור מזהה אקראי אחר. אפשר גם לנסות שם משתמש משלכם ולבדוק אם הוא זמין. אי אפשר לשנות את ההגדרה הזו אחרי השלב הזה, והיא תישאר לאורך הפרויקט.
  • לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. במאמרי העזרה מפורט מידע נוסף על שלושת הערכים האלה.
  1. בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API של Cloud. השלמת ה-codelab הזה לא תעלה לכם הרבה, אם בכלל. כדי להשבית את המשאבים ולמנוע חיובים נוספים אחרי שתסיימו את המדריך הזה, תוכלו למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.

Google Cloud Shell

אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-codelab הזה נשתמש ב-Google Cloud Shell, סביבת שורת פקודה שפועלת בענן.

הפעלת Cloud Shell

  1. ב-Cloud Console, לוחצים על Activate Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים עם תיאור של השירות. אם הוצג לכם מסך ביניים, לחצו על המשך.

d95252b003979716.png

הקצאת המשאבים והחיבור ל-Cloud Shell נמשכים רק כמה רגעים.

7833d5e1c5d18f54.png

במכונה הווירטואלית הזו טעונים כל הכלים הדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. אפשר לבצע את רוב העבודה ב-codelab הזה, אם לא את כולה, באמצעות דפדפן.

אחרי שמתחברים ל-Cloud Shell, אמור להופיע אימות ושהפרויקט מוגדר לפי מזהה הפרויקט.

  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שעברתם אימות:
gcloud auth list

פלט הפקודה

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שפקודת gcloud מכירה את הפרויקט:
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

אם לא, אפשר להגדיר אותו באמצעות הפקודה הבאה:

gcloud config set project <PROJECT_ID>

פלט הפקודה

Updated property [core/project].

3. הפעלת ממשקי Cloud API

מ-Cloud Shell, מפעילים את Cloud APIs עבור הרכיבים שבהם ישתמשו:

gcloud services enable \
  run.googleapis.com \
  sql-component.googleapis.com \
  sqladmin.googleapis.com \
  compute.googleapis.com \
  cloudbuild.googleapis.com \
  secretmanager.googleapis.com \
  artifactregistry.googleapis.com

זו הפעם הראשונה שאתם קוראים ל-APIs מ-gcloud, ולכן תתבקשו לאשר את השימוש בפרטי הכניסה שלכם כדי לבצע את הבקשה הזו. הפעולה הזו תתבצע פעם אחת בכל סשן של Cloud Shell.

הפעולה הזו עשויה להימשך כמה דקות.

בסיום התהליך, אמורה להופיע הודעת הצלחה שדומה להודעה הזו:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

4. יצירת פרויקט תבנית

תשתמשו ב-Django CMS cms-template כפרויקט לדוגמה של Django CMS.

כדי ליצור את פרויקט התבנית הזה, משתמשים ב-Cloud Shell כדי ליצור ספרייה חדשה בשם djangocms-cloudrun ועוברים אליה:

mkdir ~/djangocms-cloudrun
cd ~/djangocms-cloudrun

מתקינים את חבילת django-cms בסביבה וירטואלית זמנית:

virtualenv venv
source venv/bin/activate
pip install djangocms-frontend\[cms-4]

יוצרים עותק של פרויקט cms-template:

django-admin startproject --template https://github.com/django-cms/cms-template/archive/4.1.zip myproject .

משנים את השם של הקובץ requirements.in ל-requirements.txt. (קובץ .in נוצר על ידי pip-tools כדי ליצור קובצי requirements.txt, אבל אפשר להשתמש בו כמו שהוא אם משנים את הסיומת. בשלבים הבאים, pip מצפה לתוסף .txt.)

mv requirements.in requirements.txt

עכשיו יהיה לכם פרויקט תבנית של Django CMS בתיקייה בשם myproject:

ls -F
manage.py*  media/  myproject/  project.db requirements.txt  static/ venv/

עכשיו אפשר לצאת ולהסיר את הסביבה הווירטואלית הזמנית:

deactivate
rm -rf venv

מכאן, המערכת Django CMS תיקרא בתוך הקונטיינר.

5. יצירת שירותי הגיבוי

עכשיו יוצרים את שירותי הגיבוי: חשבון שירות ייעודי, Artifact Registry, מסד נתונים של Cloud SQL, קטגוריה של Cloud Storage ומספר ערכים של Secret Manager.

חשוב לאבטח את ערכי הסיסמאות שמשמשות לפריסה כדי לשמור על האבטחה של כל פרויקט, ולוודא שאף אחד לא יזין סיסמאות בטעות במקומות לא מתאימים (לדוגמה, ישירות בקובצי הגדרות, או בהקלדה ישירה במסוף שבו אפשר לאחזר אותן מההיסטוריה).

קודם כל, מגדירים שני משתני סביבה בסיסיים, אחד למזהה הפרויקט:

PROJECT_ID=$(gcloud config get-value core/project)

ועוד אחד לאזור:

REGION=us-central1

יצירה של חשבון שירות

כדי להגביל את הגישה של השירות לחלקים אחרים ב-Google Cloud, צריך ליצור חשבון שירות ייעודי:

gcloud iam service-accounts create cloudrun-serviceaccount

בהמשך ה-codelab הזה תצטרכו להתייחס לחשבון הזה באמצעות כתובת האימייל שלו. מגדירים את הערך הזה במשתנה סביבה:

SERVICE_ACCOUNT=$(gcloud iam service-accounts list \
    --filter cloudrun-serviceaccount --format "value(email)")

יצירת Artifact Registry

כדי לאחסן את תמונת הקונטיינר שנוצרה, יוצרים מאגר תמונות של קונטיינרים באזור שבחרתם:

gcloud artifacts repositories create containers --repository-format docker --location $REGION

תפנו למאגר הזה לפי שם בקטעים הבאים של ה-codelab:

ARTIFACT_REGISTRY=${REGION}-docker.pkg.dev/${PROJECT_ID}/containers

יצירת מסד הנתונים

יוצרים מכונה של Cloud SQL:

gcloud sql instances create myinstance --project $PROJECT_ID \
  --database-version POSTGRES_14 --tier db-f1-micro --region $REGION

הפעולה הזו עשויה להימשך כמה דקות.

במופע הזה, יוצרים מסד נתונים:

gcloud sql databases create mydatabase --instance myinstance

באותה מכונה, יוצרים משתמש:

DJPASS="$(cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 30 | head -n 1)"
gcloud sql users create djuser --instance myinstance --password $DJPASS

נותנים לחשבון השירות הרשאה להתחבר למופע:

gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:${SERVICE_ACCOUNT} \
    --role roles/cloudsql.client

יצירת קטגוריית אחסון

יוצרים קטגוריה ב-Cloud Storage (חשוב לזכור שהשם חייב להיות ייחודי באופן גלובלי):

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

מכיוון שלאובייקטים שמאוחסנים בקטגוריה יהיה מקור שונה (כתובת URL של קטגוריה ולא כתובת URL של Cloud Run), צריך להגדיר את ההגדרות של שיתוף משאבים בין מקורות (CORS).

יוצרים קובץ חדש בשם cors.json עם התוכן הבא:

touch cors.json
cloudshell edit cors.json

cors.json

[
    {
      "origin": ["*"],
      "responseHeader": ["Content-Type"],
      "method": ["GET"],
      "maxAgeSeconds": 3600
    }
]

מחילים את הגדרות ה-CORS האלה על קטגוריית האחסון החדשה שנוצרה:

gsutil cors set cors.json gs://$GS_BUCKET_NAME

שמירת ההגדרה כסוד

אחרי שמגדירים את שירותי הגיבוי, מאחסנים את הערכים האלה בקובץ שמוגן באמצעות Secret Manager.

בעזרת Secret Manager אפשר לאחסן סודות, לנהל אותם ולגשת אליהם כ-BLOB בינארי או כמחרוזות טקסט. הוא מתאים לאחסון פרטי הגדרה כמו סיסמאות למסדי נתונים, מפתחות API או אישורי TLS שנדרשים לאפליקציה בזמן הריצה.

קודם כול, יוצרים קובץ עם הערכים של מחרוזת החיבור למסד הנתונים, מאגר המדיה, מפתח סודי ל-Django (שמשמש לחתימה קריפטוגרפית של סשנים וטוקנים) וכדי להפעיל ניפוי באגים:

echo DATABASE_URL=\"postgres://djuser:${DJPASS}@//cloudsql/${PROJECT_ID}:${REGION}:myinstance/mydatabase\" > .env

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

אחר כך יוצרים Secret בשם application_settings באמצעות הקובץ הזה כ-Secret:

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

6. הגדרת האפליקציה

בהתאם לשירותי הגיבוי שיצרתם, תצטרכו לבצע כמה שינויים בפרויקט התבנית.

השינוי הזה כולל הצגה של django-environ כדי להשתמש במשתני סביבה כהגדרות התצורה, שיוזנו עם הערכים שהגדרתם כסודות. כדי להטמיע את זה, צריך להרחיב את הגדרות התבנית. תצטרכו גם להוסיף תלות נוספת ב-Python.

הגדרת ההגדרות

העברת הקובץ settings.py ושינוי השם שלו ל-basesettings.py:

mv myproject/settings.py myproject/basesettings.py

באמצעות עורך האינטרנט של Cloud Shell, יוצרים קובץ חדש בשם settings.py עם הקוד הבא:

touch myproject/settings.py
cloudshell edit 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()}

# Change database settings if using the Cloud SQL Auth Proxy
if os.getenv("USE_CLOUD_SQL_AUTH_PROXY", None):
    DATABASES["default"]["HOST"] = "127.0.0.1"
    DATABASES["default"]["PORT"] = 5432

# 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",
    },
}

חשוב להקדיש זמן לקריאת ההערות שנוספו לגבי כל הגדרה.

שימו לב: יכול להיות שיוצגו שגיאות של בדיקת קוד בקובץ הזה. זו תופעה נורמלית. ל-Cloud Shell אין הקשר של הדרישות לפרויקט הזה, ולכן יכול להיות שהוא ידווח על ייבוא לא תקין ועל ייבוא שלא נעשה בו שימוש.

יחסי תלות של Python

מאתרים את הקובץ requirements.txt ומוסיפים את החבילות הבאות:

cloudshell edit requirements.txt

requirements.txt (append)

gunicorn
psycopg2-binary
django-storages[google]
django-environ

הגדרת תמונה לאפליקציה

‫Cloud Run יריץ כל קונטיינר כל עוד הוא עומד בדרישות של הסכם הקונטיינר של Cloud Run. במדריך הזה בחרנו שלא להשתמש ב-Dockerfile, אלא ב-Cloud Native Buildpacks. ‫Buildpacks עוזרים ליצור קונטיינרים לשפות נפוצות, כולל Python.

במדריך הזה בחרנו להתאים אישית את Procfile שמשמש להפעלת אפליקציית האינטרנט.

כדי להוסיף את פרויקט התבנית לקונטיינר, קודם יוצרים קובץ חדש בשם Procfile ברמה העליונה של הפרויקט (באותה ספריה כמו manage.py) ומעתיקים את התוכן הבא:

touch Procfile
cloudshell edit Procfile

Procfile

web: gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 myproject.wsgi:application

7. הגדרה, יצירה והרצה של שלבי ההעברה

כדי ליצור את סכימת מסד הנתונים במסד הנתונים של Cloud SQL ולאכלס את קטגוריית Cloud Storage בנכסים הסטטיים, צריך להריץ את הפקודות migrate ו-collectstatic.

צריך להריץ את פקודות המיגרציה הבסיסיות של Django בהקשר של קובץ האימג' של הקונטיינר שנוצר, עם גישה למסד הנתונים.

תצטרכו גם להריץ את הפקודה createsuperuser כדי ליצור חשבון אדמין להתחברות לאדמין של Django.

כדי לעשות את זה, תשתמשו ב-Cloud Run Jobs כדי לבצע את המשימות האלה. משימות Cloud Run מאפשרות להריץ תהליכים עם סיום מוגדר, ולכן הן אידיאליות למשימות אדמיניסטרטיביות.

הגדרת סיסמת סופר-משתמש ב-Django

כדי ליצור את משתמש העל, משתמשים בגרסה הלא אינטראקטיבית של הפקודה createsuperuser. הפקודה הזו דורשת משתנה סביבה עם שם מיוחד כדי להשתמש בו במקום בקשה להזנת הסיסמה.

יוצרים סוד חדש באמצעות סיסמה שנוצרה באופן אקראי:

echo -n $(cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 30 | head -n 1) | gcloud secrets create django_superuser_password --data-file=-

מתן אפשרות לחשבון השירות לגשת לסוד הזה:

gcloud secrets add-iam-policy-binding django_superuser_password \
  --member serviceAccount:${SERVICE_ACCOUNT} \
  --role roles/secretmanager.secretAccessor

עדכון קובץ ה-Procfile

כדי להקל על ההבנה של העבודות ב-Cloud Run, אפשר ליצור קיצורי דרך ב-Procfile ולהוסיף את נקודות הכניסה הבאות ל-Procfile:

migrate: python manage.py migrate && python manage.py collectstatic --noinput --clear
createuser: python manage.py createsuperuser --username admin --email noop@example.com --noinput

עכשיו אמורות להיות שלוש נקודות כניסה: נקודת הכניסה web שמוגדרת כברירת מחדל, נקודת הכניסה migrate להחלת העברות של מסד נתונים ונקודת הכניסה createuser להפעלת הפקודה createsuperuser.

יצירת תמונת האפליקציה

אחרי שמבצעים את העדכונים ב-Procfile, יוצרים את קובץ האימג':

gcloud builds submit --pack image=${ARTIFACT_REGISTRY}/myimage

יצירת משימות ב-Cloud Run

עכשיו, אחרי שיצרתם את התמונה, אתם יכולים ליצור באמצעותה משימות של Cloud Run.

העבודות האלה משתמשות בתמונה שנבנתה קודם, אבל בערכים שונים של command. הערכים האלה ממופים לערכים ב-Procfile.

יוצרים משימה להעברה:

gcloud run jobs create migrate \
  --region $REGION \
  --image ${ARTIFACT_REGISTRY}/myimage \
  --set-cloudsql-instances ${PROJECT_ID}:${REGION}:myinstance \
  --set-secrets APPLICATION_SETTINGS=application_settings:latest \
  --service-account $SERVICE_ACCOUNT \
  --command migrate

יוצרים משימה ליצירת המשתמש:

gcloud run jobs create createuser \
  --region $REGION \
  --image ${ARTIFACT_REGISTRY}/myimage \
  --set-cloudsql-instances ${PROJECT_ID}:${REGION}:myinstance \
  --set-secrets APPLICATION_SETTINGS=application_settings:latest \
  --set-secrets DJANGO_SUPERUSER_PASSWORD=django_superuser_password:latest \
  --service-account $SERVICE_ACCOUNT \
  --command createuser

הפעלת משימות ב-Cloud Run

אחרי שמגדירים את המשימות, מריצים את ההעברות:

gcloud run jobs execute migrate --region $REGION --wait

מוודאים שהפלט של הפקודה הזו מציין שההפעלה 'הושלמה בהצלחה'.

תריצו את הפקודה הזו בהמשך, כשמבצעים עדכונים באפליקציה.

אחרי שמגדירים את מסד הנתונים, יוצרים את המשתמש באמצעות העבודה:

gcloud run jobs execute createuser --region $REGION --wait

מוודאים שהפלט של הפקודה הזו מציין שההפעלה 'הושלמה בהצלחה'.

לא תצטרכו להריץ את הפקודה הזו שוב.

8. פריסה ב-Cloud Run

אחרי שיצרתם את שירותי התמיכה ואכלסתם אותם, אתם יכולים ליצור את שירות Cloud Run כדי לגשת אליהם.

הפריסה הראשונית של האפליקציה בקונטיינר ב-Cloud Run נוצרת באמצעות הפקודה הבאה:

gcloud run deploy djangocms-cloudrun \
  --region $REGION \
  --image ${ARTIFACT_REGISTRY}/myimage \
  --set-cloudsql-instances ${PROJECT_ID}:${REGION}:myinstance \
  --set-secrets APPLICATION_SETTINGS=application_settings:latest \
  --service-account $SERVICE_ACCOUNT \
  --allow-unauthenticated

מחכים כמה רגעים עד שהפריסה תושלם. אם הפעולה בוצעה ללא שגיאות, כתובת ה-URL של השירות מוצגת בשורת הפקודה:

Service [djangocms-cloudrun] revision [djangocms-cloudrun-00001-...] has been deployed and is serving 100 percent of traffic.
Service URL: https://djangocms-cloudrun-...run.app

עכשיו אפשר להיכנס למאגר התגים שהוטמע על ידי פתיחת כתובת ה-URL הזו בדפדפן אינטרנט:

e1fb6858bf11626a.png

מכיוון שמדובר בהתקנה חדשה, תועברו אוטומטית לדף הכניסה.

9. גישה ל-Django Admin

אחת התכונות העיקריות של Django CMS היא ממשק האדמין האינטראקטיבי שלה.

עדכון הגדרות CSRF

‫Django כולל אמצעי הגנה מפני זיוף בקשות בין אתרים (CSRF). בכל פעם ששולחים טופס באתר Django, כולל התחברות לאדמין של Django, נבדקת ההגדרה Trusted Origins (מקורות מהימנים). אם הוא לא תואם למקור הבקשה, Django מחזיר שגיאה.

בקובץ mysite/settings.py, אם מוגדר משתנה הסביבה CLOUDRUN_SERVICE_URL, הוא משמש בהגדרות CSRF_TRUSTED_ORIGINS ו-ALLOWED_HOSTS. הגדרת ALLOWED_HOSTS היא לא חובה, אבל מומלץ להוסיף אותה כי היא כבר נדרשת עבור CSRF_TRUSTED_ORIGINS.

מכיוון שצריך את כתובת ה-URL של השירות, אי אפשר להוסיף את ההגדרה הזו עד אחרי הפריסה הראשונה.

תצטרכו לעדכן את השירות כדי להוסיף את משתנה הסביבה הזה. אפשר להוסיף אותו לסוד application_settings או להוסיף אותו ישירות כמשתנה סביבתי.

ההטמעה שבהמשך מתבססת על עיצוב ועל הסרת תווים מיוחדים ב-gcloud.

מאחזרים את כתובת ה-URL של השירות:

CLOUDRUN_SERVICE_URLS=$(gcloud run services describe djangocms-cloudrun \
  --region $REGION  \
  --format "value(metadata.annotations[\"run.googleapis.com/urls\"])" | tr -d '"[]')
echo $CLOUDRUN_SERVICE_URLS

מגדירים את הערך הזה כמשתנה סביבה בשירות Cloud Run:

gcloud run services update djangocms-cloudrun \
  --region $REGION \
  --update-env-vars "^##^CLOUDRUN_SERVICE_URLS=$CLOUDRUN_SERVICE_URLS"

כניסה ל-Django Admin

כדי לגשת לממשק האדמין של Django, מוסיפים /admin לכתובת ה-URL של השירות.

עכשיו מתחברים באמצעות שם המשתמש admin ומאחזרים את הסיסמה באמצעות הפקודה הבאה:

gcloud secrets versions access latest --secret django_superuser_password && echo ""

da10a148bc1c7994.png

10. החלת עדכוני אפליקציות

במהלך פיתוח האפליקציה, כדאי לבדוק אותה באופן מקומי. כדי לעשות את זה, תצטרכו להתחבר למסד הנתונים של Cloud SQL ('ייצור') או למסד נתונים מקומי ('בדיקה').

התחברות למסד הנתונים של הסביבה הפעילה

אפשר להתחבר למכונות Cloud SQL באמצעות שרת proxy ל-Cloud SQL Auth. האפליקציה הזו יוצרת חיבור מהמכונה המקומית למסד הנתונים.

אחרי שמתקינים את שרת ה-proxy ל-Cloud SQL Auth, פועלים לפי השלבים הבאים:

# Create a virtualenv
virtualenv venv
source venv/bin/activate
pip install -r requirements.txt

# Copy the application settings to your local machine
gcloud secrets versions access latest --secret application_settings > temp_settings

# Run the Cloud SQL Auth Proxy
./cloud-sql-proxy ${PROJECT_ID}:${REGION}:myinstance

# In a new tab, start the local web server using these new settings
USE_CLOUD_SQL_AUTH_PROXY=true APPLICATION_SETTINGS=$(cat temp_settings) python manage.py runserver

חשוב להקפיד להסיר את הקובץ temp_settings אחרי שמסיימים את העבודה.

התחברות למסד נתונים מקומי של SQLite

אפשרות אחרת היא להשתמש במסד נתונים מקומי כשמפתחים את האפליקציה. ‫Django תומך במסדי נתונים של PostgreSQL ו-SQLite, ויש כמה תכונות שקיימות ב-PostgreSQL ולא ב-SQLite, אבל בהרבה מקרים הפונקציונליות זהה.

כדי להגדיר את SQLite, תצטרכו לעדכן את הגדרות האפליקציה כך שיצביעו על מסד נתונים מקומי, ואז תצטרכו להחיל את העברות הסכימה.

כדי להגדיר את השיטה הזו:

# Create a virtualenv
virtualenv venv
source venv/bin/activate
pip install -r requirements.txt

# Copy the application settings to your local machine
gcloud secrets versions access latest --secret application_settings > temp_settings

# Edit the DATABASE_URL setting to use a local sqlite file. For example:
DATABASE_URL=sqlite:////tmp/my-tmp-sqlite.db

# Set the updated settings as an environment variable
APPLICATION_SETTINGS=$(cat temp_settings) 

# Apply migrations to the local database
python manage.py migrate

# Start the local web server
python manage.py runserver

חשוב להקפיד להסיר את הקובץ temp_settings אחרי שמסיימים את העבודה.

יצירת העברות

כשמבצעים שינויים במודלים של מסד הנתונים, יכול להיות שיהיה צורך ליצור את קובצי ההעברה של Django על ידי הפעלת python manage.py makemigrations.

אפשר להריץ את הפקודה הזו אחרי שמגדירים את החיבור למסד הנתונים של סביבת הייצור או של סביבת הבדיקה. אפשר גם ליצור את קובצי ההעברה בלי מסד נתונים, על ידי הגדרת הגדרות ריקות:

SECRET_KEY="" DATABASE_URL="" GS_BUCKET_NAME="" python manage.py makemigrations

החלת עדכוני אפליקציות

כדי להחיל שינויים על הבקשה, צריך:

  • ליצור תמונה חדשה עם השינויים,
  • להחיל העברות של מסדי נתונים או העברות סטטיות, ואז
  • מעדכנים את שירות Cloud Run כדי להשתמש באימג' החדש.

כדי ליצור את התמונה:

gcloud builds submit --pack image=${ARTIFACT_REGISTRY}/myimage

אם יש העברות להפעלה, מריצים את העבודה ב-Cloud Run:

gcloud run jobs execute migrate --region $REGION --wait

כדי לעדכן את השירות עם התמונה החדשה:

gcloud run services update djangocms-cloudrun \
  --platform managed \
  --region $REGION \
  --image gcr.io/${PROJECT_ID}/myimage

‫11. מעולה!

הרגע פרסתם פרויקט מורכב ב-Cloud Run.

  • ‫Cloud Run מבצע התאמה אוטומטית לעומס (autoscaling) של קובץ האימג' בקונטיינר באופן אופקי כדי לטפל בבקשות שהתקבלו, ואז מצמצם את ההקצאה כשהביקוש יורד. משלמים רק על המעבד (CPU), הזיכרון והרשת שנעשה בהם שימוש במהלך הטיפול בבקשות.
  • ‫Cloud SQL מאפשר לכם להקצות מופע מנוהל של PostgreSQL שמתוחזק אוטומטית בשבילכם, ומשתלב באופן טבעי במערכות רבות של Google Cloud.
  • בעזרת Cloud Storage אפשר לקבל אחסון בענן עם גישה חלקה ב-Django.
  • בעזרת Secret Manager אפשר לאחסן סודות, ולקבוע שחלקים מסוימים ב-Google Cloud יוכלו לגשת אליהם וחלקים אחרים לא.

פינוי נפח

כדי להימנע מחיובים בחשבון Google Cloud Platform בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה:

  • במסוף Cloud, נכנסים לדף Manage resources.
  • ברשימת הפרויקטים, בוחרים את הפרויקט ולוחצים על מחיקה.
  • כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

מידע נוסף