הפעלת Django בסביבת Cloud Run

כדי לפרוס אפליקציות עם שמירת מצב (stateful) ב-Cloud Run, כמו Django, צריך לשלב שירותים שיפעלו יחד כפרויקט אחד.

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

המדריך הזה מתמקד ב-Django, אבל אפשר להשתמש בתהליך הפריסה הזה עם מסגרות אחרות שמבוססות על Django, כמו Wagtail ו-Django CMS.

במדריך הזה משתמשים ב-Django 5, שמחייב לפחות את Python 3.10.

מטרות

במדריך הזה תלמדו:

  • ליצור מסד נתונים ב-Cloud SQL ולהתחבר אליו.
  • ליצור ולהשתמש בערכי סודות של Secret Manager.
  • פריסת אפליקציית Django ב-Cloud Run.

  • לארח קבצים סטטיים ב-Cloud Storage.

  • משתמשים ב-Cloud Build כדי להפוך את הפריסה לאוטומטית.

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

בעזרת מחשבון העלויות אתם יכולים להעריך את העלויות בהתאם לשימוש הצפוי.

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

לפני שמתחילים

  1. נכנסים לחשבון Google Cloud . אנחנו ממליצים למשתמשים חדשים ב- Google Cloud ליצור חשבון כדי שיוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Cloud Run, Cloud SQL, Cloud Build, Secret Manager, Artifact Registry, and Compute Engine APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  5. Install the gcloud CLI.

  6. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  7. To initialize the gcloud CLI, run the following command:

    gcloud init
  8. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  9. Verify that billing is enabled for your Google Cloud project.

  10. Enable the Cloud Run, Cloud SQL, Cloud Build, Secret Manager, Artifact Registry, and Compute Engine APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  11. Install the gcloud CLI.

  12. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  13. To initialize the gcloud CLI, run the following command:

    gcloud init
  14. מוודאים שיש מספיק הרשאות בחשבון שבו משתמשים במדריך הזה.

הכנת הסביבה

שכפול אפליקציה לדוגמה

הקוד של האפליקציה לדוגמה של Django נמצא במאגר GoogleCloudPlatform/python-docs-samples ב-GitHub.

  1. אתם יכולים להוריד את הדוגמה כקובץ ZIP ולחלץ אותו, או לשכפל את המאגר למכונה המקומית:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
    
  2. עוברים לספרייה שמכילה את הקוד לדוגמה:

    ‫Linux/macOS

    cd python-docs-samples/run/django
    

    Windows

    cd python-docs-samples\run\django
    

אישור ההגדרה של Python

במדריך הזה משתמשים ב-Python כדי להריץ את האפליקציה לדוגמה במחשב. כדי להשתמש בקוד לדוגמה, צריך גם להתקין יחסי תלות

מידע נוסף זמין במדריך לסביבת הפיתוח של Python.

  1. מוודאים שגרסת ה-Python היא לפחות 3.10.

     python -V
    

    צריכה להופיע הגרסה Python 3.10.0 או גרסה חדשה יותר.

  2. יוצרים סביבה וירטואלית של Python ומתקינים יחסי תלות:

    ‫Linux/macOS

    python -m venv venv
    source venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

    Windows

    python -m venv venv
    venv\scripts\activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

הורדת Cloud SQL Auth Proxy כדי להתחבר ל-Cloud SQL מהמכונה המקומית

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

‫Cloud SQL Auth Proxy משתמש ב-Cloud SQL API כדי ליצור אינטראקציה עם מכונת ה-SQL. כדי לעשות את זה, צריך לאמת את האפליקציה באמצעות ה-CLI של gcloud.

  1. מאמתים ומקבלים פרטי כניסה ל-API:

    gcloud auth application-default login
    
  2. מורידים ומתקינים את Cloud SQL Auth Proxy במחשב המקומי.

    לפני שמתחילים, צריך לזהות את הארכיטקטורה של המכונה.

    אם אתם משתמשים ב-Linux או ב-Mac, אתם יכולים להריץ את הפקודה הבאה כדי למצוא את המידע הזה:

      uname -a
      

    ‏Linux‏ 64 סיביות

    1. מורידים את Cloud SQL Auth Proxy:
      curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.26.3/cloud-sql-proxy.linux.amd64
    2. הופכים את Cloud SQL Auth Proxy לקובץ הפעלה:
      chmod +x cloud-sql-proxy

    ‏Linux‏ 32 סיביות

    1. מורידים את Cloud SQL Auth Proxy:
      curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.26.3/cloud-sql-proxy.linux.386
    2. אם הפקודה curl לא נמצאה, מריצים את sudo apt install curl וחוזרים על פקודת ההורדה.
    3. הופכים את Cloud SQL Auth Proxy לקובץ הפעלה:
      chmod +x cloud-sql-proxy

    macOS‏ 64 סיביות

    1. מורידים את Cloud SQL Auth Proxy:
      curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.26.3/cloud-sql-proxy.darwin.amd64
    2. הופכים את Cloud SQL Auth Proxy לקובץ הפעלה:
      chmod +x cloud-sql-proxy

    Mac M1

    1. מורידים את Cloud SQL Auth Proxy:
        curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.26.3/cloud-sql-proxy.darwin.arm64
        
    2. הופכים את Cloud SQL Auth Proxy לקובץ הפעלה:
        chmod +x cloud-sql-proxy
        

    ‏Windows‏ 64 סיביות

    לוחצים לחיצה ימנית על הקישור https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.26.3/cloud-sql-proxy.x64.exe ובוחרים באפשרות Save Link As כדי להוריד את Cloud SQL Auth Proxy. משנים את שם הקובץ ל-cloud-sql-proxy.exe.

    ‏Windows‏ 32 סיביות

    לוחצים לחיצה ימנית על הקישור https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.26.3/cloud-sql-proxy.x86.exe ובוחרים באפשרות Save Link As כדי להוריד את Cloud SQL Auth Proxy. משנים את שם הקובץ ל-cloud-sql-proxy.exe.

    קובץ אימג' של Docker ל-Cloud SQL Auth Proxy

    ל-Cloud SQL Auth Proxy יש קובצי אימג' שונים של קונטיינרים, כמו distroless,‏ alpine ו-buster. קובץ האימג' של הקונטיינר שמשמש כברירת מחדל ל-Cloud SQL Auth Proxy משתמש ב-distroless, שלא מכיל מעטפת. אם אתם צריכים מעטפת או כלים קשורים, הורידו קובץ אימג' שמבוסס על alpine או על buster. מידע נוסף מופיע במאמר קובצי אימג' של קונטיינרים של Cloud SQL Auth Proxy.

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

    docker pull gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.26.3
    

    מערכת הפעלה אחרת

    במערכות הפעלה אחרות שלא מופיעות כאן, אפשר להדר את Cloud SQL Auth Proxy מהמקור.

    אפשר להעביר את ההורדה למיקום נפוץ, כמו מיקום ב-PATH או ספריית הבית. אם תבחרו לעשות את זה, כשתפעילו את Cloud SQL Auth Proxy בהמשך המדריך, זכרו להפנות למיקום שבחרתם כשאתם משתמשים בפקודות cloud-sql-proxy.

יצירת שירותים תומכים

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

במדריך הזה משתמשים במנגנונים המשולבים לאירוח נכסים סטטיים ב-Cloud Run.

הגדרת מכונה של Cloud SQL ל-PostgreSQL

Django תומך באופן רשמי במספר מסדי נתונים רלציוניים, אבל התמיכה הטובה ביותר היא ב-PostgreSQL. ‫Cloud SQL תומך ב-PostgreSQL, ולכן במדריך הזה נשתמש בסוג הזה של מסד נתונים.

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

  1. יוצרים את מכונת PostgreSQL:

    המסוף

    1. נכנסים לדף Cloud SQL Instances במסוף Google Cloud .

      כניסה לדף Cloud SQL Instances

    2. לוחצים על Create Instance.

    3. לוחצים על Choose PostgreSQL.

    4. ב-SQL Edition, בוחרים באפשרות Enterprise.

    5. בקטע Edition Preset, בוחרים באפשרות Sandbox.

    6. בשדה Instance ID, מזינים את הערך INSTANCE_NAME.

    7. מזינים סיסמה למשתמש postgres.

    8. משאירים את ערכי ברירת המחדל בשאר השדות.

    9. לוחצים על Create Instance.

    המכונה תהיה מוכנה לשימוש תוך כמה דקות.

    gcloud

    • יוצרים את מכונת PostgreSQL:

      gcloud sql instances create INSTANCE_NAME \
          --project PROJECT_ID \
          --database-version POSTGRES_16 \
          --tier db-n1-standard-2 \
          --region REGION
      

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫INSTANCE_NAME: השם של מכונת Cloud SQL
    • ‫PROJECT_ID: מזהה הפרויקט ב- Google Cloud
    • ‫REGION: Google Cloud האזור

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

  2. במכונה שנוצרה, יוצרים מסד נתונים:

    המסוף

    1. בדף המכונה, נכנסים לכרטיסייה Databases.
    2. לוחצים על Create database.
    3. בתיבת הדו-שיח Database Name, מזינים DATABASE_NAME.
    4. לוחצים על יצירה.

    gcloud

    • יוצרים את מסד הנתונים במכונה שנוצרה לאחרונה:

      gcloud sql databases create DATABASE_NAME \
          --instance INSTANCE_NAME
      

      מחליפים את DATABASE_NAME בשם של מסד הנתונים בתוך המכונה.

  3. יוצרים משתמש במסד הנתונים:

    המסוף

    1. בדף המכונה, עוברים לכרטיסייה Users.
    2. לוחצים על הוספת חשבון משתמש.
    3. בתיבת הדו-שיח בחירת שיטת אימות, בקטע "אימות מובנה":
    4. מזינים את שם המשתמש DATABASE_USERNAME.
    5. מזינים את הסיסמה DATABASE_PASSWORD
    6. לוחצים על הוספה.

    gcloud

    • יוצרים את המשתמש במכונה שנוצרה לאחרונה:

      gcloud sql users create DATABASE_USERNAME \
          --instance INSTANCE_NAME \
          --password DATABASE_PASSWORD
      

      מחליפים את PASSWORD בסיסמה מאובטחת.

הגדרת Artifact Registry

משתמשים ב-Artifact Registry כדי ליצור מאגר לאחסון קובץ האימג' של הקונטיינר.

המסוף

  1. נכנסים לדף Artifact Registry במסוף Google Cloud .

    כניסה לדף Artifact Registry

  2. לוחצים על Create Repository.

  3. כתבו:

    • בשדה Name, מזינים "cloud-run-source-deploy".
    • בשדה Format, בוחרים באפשרות Docker.
    • בשדה Region, בוחרים באפשרות REGION.
  4. משאירים את ערכי ברירת המחדל בשאר השדות.

  5. לוחצים על יצירה.

gcloud

  • יוצרים Artifact Registry:
gcloud artifacts repositories create cloud-run-source-deploy \
    --repository-format docker \
    --location REGION

הגדרת קטגוריה של Cloud Storage

אתם יכולים לאחסן את הנכסים הסטטיים שכלולים ב-Django, וגם מדיה שהמשתמשים העלו, במאגר אובייקטים עם זמינות גבוהה באמצעות Cloud Storage. החבילה django-storages[google] מטפלת באינטראקציה של Django עם הקצה העורפי של האחסון.

המסוף

  1. פותחים את הדף Cloud Storage במסוף Google Cloud .

    כניסה לדף Cloud Storage

  2. לוחצים על Create Bucket.

  3. מזינים את הפרטים הבאים (לוחצים על "המשך" לפי הצורך):

    • בשדה Name, מזינים "PROJECT_ID_MEDIA_BUCKET".
    • בשדה Region, בוחרים באפשרות REGION.
    • משאירים את ערכי ברירת המחדל בשדה Storage Class.
    • בקטע Prevent public access, מבטלים את הסימון של "Enforce public access prevention".
    • בקטע בקרת גישה, בוחרים באפשרות Fine-grained.
  4. משאירים את ערכי ברירת המחדל בשאר השדות.

  5. לוחצים על יצירה.

gcloud

  • יוצרים קטגוריה של Cloud Storage:

    gcloud storage buckets create gs://PROJECT_ID_MEDIA_BUCKET --location=REGION
    

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

אחסון ערכים סודיים ב-Secret Manager

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

יצירת קובץ סביבה של Django כסוד ב-Secret Manager

אתם שומרים את ההגדרות שנדרשות כדי להפעיל את Django בקובץ env מאובטח. האפליקציה לדוגמה משתמשת ב-Secret Manager API כדי לאחזר את ערך הסוד, ובחבילה django-environ כדי לטעון את הערכים לסביבת Django. הסוד מוגדר כך ש-Cloud Run ו-Cloud Build יוכלו לגשת אליו.

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

    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
    
  2. מאחסנים את הסוד ב-Secret Manager:

    המסוף

    1. נכנסים לדף Secret Manager במסוף Google Cloud .

      כניסה לדף Secret Manager

    2. לוחצים על Create secret.

    3. בשדה Name, מזינים django_settings.

    4. בתיבת הדו-שיח Secret value, מדביקים את התוכן של קובץ ה-.env.

    5. לוחצים על Create secret.

    6. מוחקים את הקובץ המקומי כדי למנוע שינוי של ההגדרות המקומיות.

    gcloud

    1. יוצרים סוד חדש, django_settings, עם הערך של הקובץ .env:

      gcloud secrets create django_settings --data-file .env
      
    2. כדי למנוע שינויים מקומיים בהגדרות, צריך למחוק את הקובץ המקומי:

      rm .env
      
  3. מגדירים את הגישה לסוד:

    המסוף

    לפני שמגדירים את הגישה לסוד, שימו לב למספר הפרויקט ב-Secret: django_settings:

        projects/PROJECTNUM/secrets/django_settings
    
    1. לוחצים על הכרטיסייה Permissions.
    2. לוחצים על הענקת גישה.
    3. בשדה רק הצטרפתי, מזינים את הערך PROJECTNUM-compute@developer.gserviceaccount.com ולוחצים על Enter.
    4. בתפריט הנפתח Role, בוחרים באפשרות Secret Manager Secret Accessor.
    5. לוחצים על Save.

    gcloud

    נותנים לחשבון השירות של Cloud Run גישה לסוד:

      gcloud secrets add-iam-policy-binding django_settings \
          --member serviceAccount:PROJECTNUM-compute@developer.gserviceaccount.com \
          --role roles/secretmanager.secretAccessor
    

    כדי לקבל את הערך של מספר הפרויקט (PROJECTNUM), משתמשים בפקודה הבאה:

      gcloud projects describe PROJECT_ID --format='value(projectNumber)'
    

    בפלט, מוודאים שחשבון השירות החדש מופיע ב-bindings.

יצירת סוד לסיסמת האדמין של Django

בדרך כלל, המשתמש עם הרשאת אדמין ב-Django נוצר על ידי הפעלת פקודת הניהול האינטראקטיבית createsuperuser.

במדריך הזה משתמשים בהעברת נתונים כדי ליצור את משתמש האדמין, ושולפים את סיסמת האדמין מ-Secret Manager.

המסוף

  1. נכנסים לדף Secret Manager במסוף Google Cloud .
  2. לוחצים על Create secret.

  3. בשדה Name, מזינים superuser_password.

  4. בשדה ערך סודי, מזינים סיסמה אקראית וייחודית.

  5. לוחצים על Create secret.

  6. בקטע Details for superuser_password, מאתרים את מספר הפרויקט (projects/PROJECTNUM/secrets/superuser_password).

  7. לוחצים על הכרטיסייה Permissions.

  8. לוחצים על הוספה.

  9. בשדה רק הצטרפתי, מזינים את הערך PROJECTNUM-compute@developer.gserviceaccount.com ולוחצים על Enter.

  10. בתפריט הנפתח Role, בוחרים באפשרות Secret Manager Secret Accessor.

  11. לוחצים על שמירה.

gcloud

  1. יוצרים סוד חדש, superuser_password, מסיסמה שנוצרה באופן אקראי:

    echo -n "$(cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]'| fold -w 30 | head -n1)" | gcloud secrets create superuser_password --data-file -
    
  2. נותנים ל-Cloud Build גישה לסוד:

    gcloud secrets add-iam-policy-binding superuser_password \
        --member serviceAccount:PROJECTNUM-compute@developer.gserviceaccount.com \
        --role roles/secretmanager.secretAccessor
    

    בפלט, מוודאים ש-bindings מציג רק את Cloud Build כחבר.

הפעלת האפליקציה במחשב המקומי

אחרי שהגדרתם את שירותי הגיבוי, אתם יכולים להריץ את האפליקציה במחשב. ההגדרה הזו מאפשרת פיתוח מקומי והחלת העברות של מסדי נתונים. חשוב לזכור שהעברות של מסדי נתונים מתבצעות גם ב-Cloud Build, אבל צריך את ההגדרה המקומית הזו כדי makemigrations.

  1. בטרמינל נפרד, מפעילים את Cloud SQL Auth Proxy:

    ‫Linux/macOS

    ./cloud-sql-proxy PROJECT_ID:REGION:INSTANCE_NAME
    

    Windows

    cloud-sql-proxy.exe PROJECT_ID:REGION:INSTANCE_NAME
    

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

  2. בטרמינל המקורי, מגדירים את מזהה הפרויקט באופן מקומי (משמש את Secret Manager API):

    ‫Linux/macOS

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID
    

    Windows

    set GOOGLE_CLOUD_PROJECT=PROJECT_ID
    
  3. מגדירים משתנה סביבה כדי לציין שאתם משתמשים ב-Cloud SQL Auth Proxy (הערך הזה מזוהה בקוד):

    ‫Linux/macOS

    export USE_CLOUD_SQL_AUTH_PROXY=true
    

    Windows

    set USE_CLOUD_SQL_AUTH_PROXY=true
    
  4. מריצים את ההעברות של Django כדי להגדיר את המודלים והנכסים:

    python manage.py makemigrations
    python manage.py makemigrations polls
    python manage.py migrate
    python manage.py collectstatic
    
  5. מפעילים את שרת האינטרנט של Django:

    python manage.py runserver 8080
    
  6. בדפדפן, עוברים אל http://localhost:8080.

    אם אתם ב-Cloud Shell, לוחצים על הכפתור Web Preview ובוחרים באפשרות Preview on port 8080.

    בדף מופיע הטקסט הבא: "Hello, world. הגעת לאינדקס הסקרים". שרת האינטרנט של Django שפועל במחשב שלכם מספק את דפי האפליקציה לדוגמה.

  7. מקישים על Ctrl/Cmd+C כדי לעצור את שרת האינטרנט המקומי.

פריסת האפליקציה ב-Cloud Run

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

  1. משתמשים ב-cloudmigrate.yaml שסופק כדי להפעיל את Cloud Build, ליצור את קובץ האימג', להריץ את ההעברות של מסד הנתונים ולאכלס את הנכסים הסטטיים:

    gcloud builds submit --config cloudmigrate.yaml \
        --substitutions _INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION
    

    ה-build הראשון הזה נמשך כמה דקות.

  2. אחרי שה-build מסתיים בהצלחה, פורסים את שירות Cloud Run בפעם הראשונה, ומגדירים את אזור השירות, קובץ האימג' הבסיסי ומכונת Cloud SQL המחוברת:

    gcloud run deploy polls-service \
        --region REGION \
        --image REGION-docker.pkg.dev/PROJECT_ID/cloud-run-source-deploy/polls-service \
        --add-cloudsql-instances PROJECT_ID:REGION:INSTANCE_NAME \
        --allow-unauthenticated
    

    הפלט אמור להראות שהפריסה הצליחה, עם כתובת URL של השירות:

    Service [polls-service] revision [polls-service-00001-tug] has been deployed
    and is serving 100 percent of traffic.
    Service URL: https://polls-service-PROJECT_ID.REGION.run.app
    
  3. מעדכנים את השירות לכתובות ה-URL של השירות כמשתנה סביבה.

    CLOUDRUN_SERVICE_URLS=$(gcloud run services describe polls-service \
        --region $REGION  \
        --format "value(metadata.annotations[\"run.googleapis.com/urls\"])" | tr -d '"[]')
    
    gcloud run services update polls-service \
        --region REGION \
        --update-env-vars "^##^CLOUDRUN_SERVICE_URLS=$CLOUDRUN_SERVICE_URLS"
    
  4. כדי לראות את השירות שנפרס, עוברים לכתובת ה-URL של השירות.

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

    כדי לאחזר את הסיסמה של משתמש-העל מ-Secret Manager:

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

עדכון האפליקציה

השלבים הראשונים של ההקצאה והפריסה היו מורכבים, אבל תהליך העדכון פשוט יותר:

  1. מריצים את הסקריפט של Cloud Build ליצירה ולהעברה:

    gcloud builds submit --config cloudmigrate.yaml \
        --substitutions _INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION
    
  2. פורסים את השירות ומציינים רק את האזור והתמונה:

    gcloud run deploy polls-service \
        --region REGION \
        --image REGION-docker.pkg.dev/PROJECT_ID/cloud-run-source-deploy/polls-service
    

הגדרה לסביבת ייצור

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

השבתת ניפוי הבאגים

מוודאים שהמשתנה DEBUG ב-mysite/settings.py מוגדר כ-False. כך המשתמש לא יראה דפי שגיאה מפורטים, שעלולים להדליף מידע על ההגדרות האישיות.

הגבלת הרשאות המשתמשים במסד הנתונים

לכל המשתמשים שנוצרים באמצעות Cloud SQL יש את ההרשאות שמשויכות לתפקיד cloudsqlsuperuser: CREATEROLE,‏ CREATEDB ו-LOGIN.

כדי למנוע ממשתמש מסד הנתונים של Django לקבל את ההרשאות האלה, צריך ליצור את המשתמש באופן ידני ב-PostgreSQL. צריך להתקין את הטרמינל האינטראקטיבי של psql, או להשתמש ב-Cloud Shell שבו הכלי הזה מותקן מראש.

המסוף

  1. מפעילים את Cloud Shell במסוף Google Cloud .

    הפעלת Cloud Shell

  2. ב-Cloud Shell, משתמשים בטרמינל המובנה כדי להתחבר למכונה של INSTANCE_NAME:

    gcloud sql connect INSTANCE_NAME --user postgres
    
  3. מזינים את סיסמת המשתמש של postgres.

    המודל שלך כרגע הוא psql. אמורה להופיע ההנחיה postgres=>.

  4. יצירת משתמש:

    CREATE USER DATABASE_USERNAME WITH PASSWORD 'DATABASE_PASSWORD';
    

    מחליפים את PASSWORD בסיסמה ייחודית ואקראית.

  5. מעניקים למשתמש החדש הרשאות מלאות במסד הנתונים החדש:

    GRANT ALL PRIVILEGES ON DATABASE DATABASE_NAME TO DATABASE_USERNAME;
    
  6. יציאה psql:

    \q
    

gcloud

  1. מתחילים חיבור למכונה של SQL:

    gcloud sql connect INSTANCE_NAME --user postgres
    

    מחליפים את INSTANCE_NAME במכונה של Cloud SQL שנוצרה.

  2. מזינים את סיסמת המשתמש של postgres.

    המודל שלך כרגע הוא psql. אמורה להופיע ההנחיה postgres=>.

  3. יצירת משתמש:

    CREATE USER DATABASE_USERNAME WITH PASSWORD 'DATABASE_PASSWORD';
    
  4. מעניקים למשתמש החדש הרשאות מלאות במסד הנתונים החדש:

    GRANT ALL PRIVILEGES ON DATABASE DATABASE_NAME TO DATABASE_USERNAME;
    
  5. יציאה psql:

    \q
    

הגדרת הרשאות מינימליות

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

אלה התפקידים המינימליים שנדרשים בפרויקט בשביל השירות הזה:

  • Cloud Run Invoker
  • לקוח Cloud SQL
  • אדמין אחסון, בקטגוריית המדיה
  • ‫Secret Manager Accessor, בסוד של הגדרות Django. (השירות עצמו לא צריך גישה לסוד של Django admin).

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

  1. ב-CLI של gcloud, יוצרים חשבון שירות עם התפקידים הנדרשים:

    gcloud iam service-accounts create polls-service-account
    SERVICE_ACCOUNT=polls-service-account@PROJECT_ID.iam.gserviceaccount.com
    
    # Cloud SQL Client
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:${SERVICE_ACCOUNT} \
        --role roles/cloudsql.client
    
    # Storage Admin, on the media bucket
    gcloud storage buckets add-iam-policy-binding gs://MEDIA_BUCKET \
        --member=serviceAccount:${SERVICE_ACCOUNT} \
        --role=roles/storage.objectAdmin
    
    # Secret Accessor, on the Django settings secret.
    gcloud secrets add-iam-policy-binding django_settings \
        --member serviceAccount:${SERVICE_ACCOUNT} \
        --role roles/secretmanager.secretAccessor
    
    # Secret Accessor, on the Django super user password.
    gcloud secrets add-iam-policy-binding superuser_password \
        --member serviceAccount:${SERVICE_ACCOUNT} \
        --role roles/secretmanager.secretAccessor
    
  2. פורסים את השירות ומשייכים אותו לחשבון השירות החדש:

    gcloud run services update polls-service \
        --region REGION \
        --service-account ${SERVICE_ACCOUNT}
    
  3. מעדכנים את המשימות של Cloud Run בפרויקט cloudmigrate.yaml כך שיכללו גם את ההגדרה --service-account.

הבנת הקוד

אפליקציה לדוגמה

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

django-admin startproject mysite
python manage.py startapp polls

התצוגות, המודלים והגדרות הניתוב הבסיסיים הועתקו מהמדריך Writing your first Django app (חלק 1 וחלק 2).

סודות מ-Secret Manager

הקובץ settings.py מכיל קוד שמשתמש ב-API בשפת Python של Secret Manager כדי לאחזר את הגרסה העדכנית של הסוד שצוין, ולהעביר אותו לסביבה (באמצעות django-environ):

# SECURITY WARNING: don't run with debug turned on in production!
# Change this to "False" when you are ready for production
env = environ.Env(DEBUG=(bool, True))
env_file = os.path.join(BASE_DIR, ".env")

# Attempt to load the Project ID into the environment, safely failing on error.
try:
    _, os.environ["GOOGLE_CLOUD_PROJECT"] = google.auth.default()
except google.auth.exceptions.DefaultCredentialsError:
    pass

if os.path.isfile(env_file):
    # Use a local secret file, if provided

    env.read_env(env_file)
# ...
elif os.environ.get("GOOGLE_CLOUD_PROJECT", None):
    # 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))
else:
    raise Exception("No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.")

הסוד משמש לאחסון כמה ערכי סודות כדי לצמצם את מספר הסודות השונים שצריך להגדיר.

הגדרות CSRF

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

אתם מספקים את כתובת ה-URL של האפליקציה כמשתנה סביבה בקובץ settings.py. זה הערך שבו Django משתמש להגדרות הרלוונטיות.

# SECURITY WARNING: It's recommended that you use this when
# running in production. The URLs will be known once you first deploy
# to Cloud Run. This code takes the URLs and converts it to both these settings formats.
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]

    SECURE_SSL_REDIRECT = True
    SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
else:
    ALLOWED_HOSTS = ["*"]

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

אם נמצא קובץ .env במערכת הקבצים המקומית, המערכת משתמשת בו במקום בערך מ-Secret Manager. יצירת קובץ .env באופן מקומי יכולה לעזור בבדיקות מקומיות (למשל, פיתוח מקומי מול מסד נתונים של SQLite או הגדרות מקומיות אחרות).

חיבור למסד נתונים

הקובץ settings.py מכיל את ההגדרות של מסד הנתונים ב-SQL. הוא משתמש ברכיב העזר env.db() מ-django-environ כדי לטעון את מחרוזת החיבור שמוגדרת ב-DATABASE_URL להגדרה DATABASES.

כשמריצים את האפליקציה באופן מקומי ומשתמשים ב-Cloud SQL Auth Proxy כדי לגשת למסד הנתונים שמתארח, הדגל USE_CLOUD_SQL_AUTH_PROXY משנה את ההגדרות של מסד הנתונים כדי להשתמש בשרת ה-proxy.

# Use django-environ to parse the connection string
DATABASES = {"default": env.db()}

# If the flag as been set, configure to use proxy
if os.getenv("USE_CLOUD_SQL_AUTH_PROXY", None):
    DATABASES["default"]["HOST"] = "127.0.0.1"
    DATABASES["default"]["PORT"] = 5432

סטטי, מאוחסן בענן

הקובץ settings.py משתמש גם ב-django-storages כדי לשלב את קטגוריית המדיה של Cloud Storage ישירות בפרויקט:

# Define static storage via django-storages[google]
GS_BUCKET_NAME = env("GS_BUCKET_NAME")
STATIC_URL = "/static/"
STORAGES = {
    "default": {
        "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
    },
    "staticfiles": {
        "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
    },
}
GS_DEFAULT_ACL = "publicRead"

אוטומציה באמצעות Cloud Build

ה-cloudmigrate.yaml מטפל בכל השלבים הנדרשים כדי ליצור קובץ אימג' חדש של קונטיינר, ולהשתמש בו כדי להחיל העברות של מסדי נתונים.

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

steps:
  - id: "Build Container Image"
    name: gcr.io/k8s-skaffold/pack
    args: ["build", "${_IMAGE_NAME}", "--builder=gcr.io/buildpacks/builder"]

  - id: "Push Container Image"
    name: "gcr.io/cloud-builders/docker"
    args: ["push", "${_IMAGE_NAME}"]

  - id: "Migrate database"
    name: "gcr.io/google.com/cloudsdktool/cloud-sdk"
    entrypoint: /bin/bash
    args:
      - "-c"
      - |
        gcloud run jobs create migrate-job \
          --region ${_REGION} \
          --image ${_IMAGE_NAME} \
          --set-cloudsql-instances ${_CLOUD_SQL_CONNECTION_NAME} \
          --set-env-vars SETTINGS_NAME=${_SECRET_SETTINGS_NAME} \
          --command migrate \
          --execute-now

  - id: "Create superuser"
    name: "gcr.io/google.com/cloudsdktool/cloud-sdk"
    entrypoint: /bin/bash
    args:
      - "-c"
      - |
        gcloud run jobs create superuser-job \
          --region ${_REGION} \
          --image ${_IMAGE_NAME} \
          --set-cloudsql-instances ${_CLOUD_SQL_CONNECTION_NAME} \
          --set-env-vars SETTINGS_NAME=${_SECRET_SETTINGS_NAME} \
          --set-env-vars DJANGO_SUPERUSER_EMAIL=${_ADMIN_EMAIL} \
          --set-secrets DJANGO_SUPERUSER_PASSWORD=${_ADMIN_PASSWORD_NAME}:latest \
          --command createsuperuser \
          --execute-now

options:
  dynamicSubstitutions: true

substitutions:
  _INSTANCE_NAME: django-instance
  _CLOUD_SQL_CONNECTION_NAME: ${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}
  _REGION: us-central1
  _SERVICE_NAME: polls-service
  _SECRET_SETTINGS_NAME: django_settings
  _ARTIFACT_REGISTRY: cloud-run-source-deploy
  _IMAGE_NAME: ${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY}/${_SERVICE_NAME}
  _ADMIN_EMAIL: example@example.com
  _ADMIN_PASSWORD_NAME: superuser_password

images:
  - "${_IMAGE_NAME}"

בתצורה הזו נעשה שימוש במשתני החלפה.

יצירת משתמש-על באמצעות משימות Cloud Run

אפשר להריץ את פקודת הניהול של Django‏ createsuperuser באופן לא אינטראקטיבי על ידי הגדרת DJANGO_SUPERUSER_EMAIL ו-DJANGO_SUPERUSER_PASSWORD.

במדריך הזה נשתמש במשימות של Cloud Run כדי להריץ את הפקודה הזו. כדי לעשות את זה, מוסיפים רשומה בהתאמה אישית ל-Procfile שמפעילה את createsuperuser.

# Create superuser (requires DJANGO_SUPERUSER_PASSWORD and DJANGO_SUPERUSER_EMAIL envvars)
createsuperuser: python manage.py createsuperuser --username admin --noinput || echo "User already exists."

הסרת המשאבים

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

מחיקת הפרויקט

  1. במסוף Google Cloud , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

המאמרים הבאים