1. 簡介
Cloud Run 是代管運算平台,能夠讓您執行可透過 HTTP 要求叫用的無狀態容器。Cloud Run 採用無伺服器技術,可為您省去所有基礎架構管理工作,讓您專心處理最重要的事物,也就是建構出色的應用程式。
另外,這項服務也會與 Google Cloud 生態系統的許多其他部分原生通訊,包括適用於代管資料庫的 Cloud SQL、適用於統一物件儲存空間的 Cloud Storage,以及用於管理密鑰的 Secret Manager。
Django 是高階的 Python 網路架構。
在這個教學課程中,您將使用這些元件來部署小型的 Django 專案。
注意:本程式碼研究室上次透過 Django 5.0 驗證。除非日後更新有任何破壞性變更,否則本程式碼研究室應可持續運作。查看未來的 Django 版本資訊。
課程內容
- 如何使用 Cloud Shell
- 如何建立 Cloud SQL 資料庫
- 如何建立 Cloud Storage 值區
- 如何建立 Secret Manager 密鑰
- 如何使用不同 Google Cloud 服務的 Secret
- 如何將 Google Cloud 元件連結至 Cloud Run 服務
- 如何使用 Container Registry 儲存建構的容器
- 如何部署至 Cloud Run
- 如何在 Cloud Build 中執行資料庫結構定義遷移作業
2. 設定和需求
自修環境設定
- 登入 Google Cloud 控制台,建立新專案或重複使用現有專案。如果您還沒有 Gmail 或 Google Workspace 帳戶,請先建立帳戶。
- 「專案名稱」是這項專案參與者的顯示名稱。這是 Google API 未使用的字元字串。你隨時可以更新。
- 所有 Google Cloud 專案的專案 ID 均不得重複,而且設定後即無法變更。Cloud 控制台會自動產生一個不重複的字串。但通常是在乎它何在在大部分的程式碼研究室中,您必須參照專案 ID (通常為
PROJECT_ID
)。如果您對產生的 ID 不滿意,可以隨機產生一個 ID。或者,您也可以自行嘗試,看看是否支援。在這個步驟後,這個名稱即無法變更,而且在專案期間內仍會保持有效。 - 資訊中的第三個值是專案編號,部分 API 會使用這個編號。如要進一步瞭解這三個值,請參閱說明文件。
- 接下來,您需要在 Cloud 控制台中啟用計費功能,才能使用 Cloud 資源/API。執行本程式碼研究室不會產生任何費用 (如果有的話)。如要關閉資源,以免產生本教學課程結束後產生的費用,您可以刪除自己建立的資源或刪除專案。新使用者符合 $300 美元免費試用計畫的資格。
Google Cloud Shell
雖然 Google Cloud 可以在筆電上遠端操作,但在本程式碼研究室中,我們會使用 Google Cloud Shell,這是 Cloud 中運作的指令列環境。
啟用 Cloud Shell
- 在 Cloud 控制台中,按一下「啟用 Cloud Shell」圖示 。
如果您是第一次啟動 Cloud Shell,系統會顯示中繼畫面,說明這項服務的內容。如果系統顯示中繼畫面,請按一下「繼續」。
佈建並連線至 Cloud Shell 只需幾分鐘的時間。
這個虛擬機器已載入所有必要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。在本程式碼研究室中,您的大部分作業都可透過瀏覽器完成。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。
- 在 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`
- 在 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 API:
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
由於這是您第一次透過 gcloud 呼叫 API,系統會要求您使用憑證來發出這項要求。每個 Cloud Shell 工作階段都需要執行一次。
這項作業可能需要幾分鐘才能完成。
完成後,畫面上應該會顯示類似以下的成功訊息:
Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.
4. 建立範本專案
您將使用預設的 Django 專案範本做為您的 Django 專案範例。
如要建立這個範本專案,請使用 Cloud Shell 建立名為 django-cloudrun
的新目錄,然後前往該目錄:
mkdir ~/django-cloudrun cd ~/django-cloudrun
然後,將 Django 安裝到臨時虛擬環境中:
virtualenv venv source venv/bin/activate pip install Django
儲存安裝至「requirements.txt
」的套件清單
pip freeze > requirements.txt
這份清單應包含 Django 及其依附元件:sqlparse
和 asgiref
。
接著,建立新的範本專案:
django-admin startproject myproject .
您將取得名為 manage.py
的新檔案,以及名為 myproject
的新資料夾,其中包含許多檔案,包括 settings.py
。
確認頂層資料夾的內容符合預期:
ls -F
manage.py myproject/ requirements.txt venv/
確認 myproject
資料夾的內容是否符合預期:
ls -F myproject/
__init__.py asgi.py settings.py urls.py wsgi.py
您現在可以離開並移除臨時的虛擬環境:
deactivate rm -rf venv
從這裡開始,在容器中呼叫 Django。
5. 建立後端服務
您現在要建立備份服務,包括專屬服務帳戶、Artifact Registry、Cloud SQL 資料庫、Cloud Storage 值區,以及一些 Secret Manager 值。
保護部署中所用密碼的值對任何專案的安全性至關重要,並確保沒有人不小心將不合適的密碼放入密碼 (例如,直接在設定檔中或終端機輸入,以便從歷史記錄擷取密碼)。
首先,請為專案 ID 設定兩個基本環境變數:
PROJECT_ID=$(gcloud config get-value core/project)
一個用於區域:
REGION=us-central1
建立服務帳戶
如要限制服務只能存取 Google Cloud 的其他部分,請建立專屬的服務帳戶:
gcloud iam service-accounts create cloudrun-serviceaccount
在本程式碼研究室的後續章節中,我們會以電子郵件地址參照這個帳戶。在環境變數中設定該值:
SERVICE_ACCOUNT=$(gcloud iam service-accounts list \ --filter cloudrun-serviceaccount --format "value(email)")
建立 Artifact Registry
如要儲存建構的容器映像檔,請在所選區域中建立 Container Registry:
gcloud artifacts repositories create containers --repository-format docker --location $REGION
在本程式碼研究室的後續章節中,我們會依名稱參照這個登錄檔:
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
將設定儲存為 Secret
設定備份服務後,您現在會將這些值儲存在使用 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
接著,建立名為 application_settings
的密鑰,並使用該檔案做為密鑰:
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
確認 Secret 已建立後,移除本機檔案:
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 URL to Django security settings
CLOUDRUN_SERVICE_URL = env("CLOUDRUN_SERVICE_URL", default=None)
if CLOUDRUN_SERVICE_URL:
ALLOWED_HOSTS = [urlparse(CLOUDRUN_SERVICE_URL).netloc]
CSRF_TRUSTED_ORIGINS = [CLOUDRUN_SERVICE_URL]
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 = []
DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
STATICFILES_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
GS_DEFAULT_ACL = "publicRead"
請花點時間閱讀關於每項設定新增的解說。
請注意,這個檔案可能會顯示程式碼檢查錯誤。這個狀況有可能發生:Cloud Shell 沒有這項專案的規定背景資訊,因此可能會回報無效的匯入項目和未使用的匯入作業。
Python 依附元件
找出 requirements.txt
檔案並附加下列套件:
cloudshell edit requirements.txt
requirements.txt (附加)
gunicorn psycopg2-binary django-storages[google] django-environ
定義應用程式映像檔
只要容器符合 Cloud Run 容器合約,Cloud Run 就會執行。本教學課程選擇省略 Dockerfile
,但改用 Cloud Native Buildpacks。Buildpacks 能協助您建構常見語言 (包括 Python) 的容器。
本教學課程選擇自訂 Procfile,用於啟動網頁應用程式。
如要將範本專案容器化,請先在專案頂層 (與 manage.py
相同的目錄中) 建立名為 Procfile
的新檔案,然後複製下列內容:
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 工作來執行這些工作。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
您現在應有三個項目:預設網路進入點、用來套用資料庫遷移作業的 migrate
進入點,以及執行 createsuperuser
指令的 createuser
進入點。
建構應用程式映像檔
更新 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 django-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
部署成功之後,指令列會顯示服務網址:
Service [django-cloudrun] revision [django-cloudrun-00001-...] has been deployed and is serving 100 percent of traffic. Service URL: https://django-cloudrun-...-uc.a.run.app
您現在可以在網路瀏覽器中開啟這個網址,造訪您部署的容器:
9. 存取 Django 管理員
Django 的其中一項主要功能是互動式管理員。
更新 CSRF 設定
Django 包含針對跨網站要求偽造 (CSRF) 的保護措施。每當有表單提交至 Django 網站時 (包括登入 Django 管理員),系統都會檢查「信任來源」設定。如果與要求的來源不相符,Django 會傳回錯誤。
在 mysite/settings.py
檔案中,如果 CLOUDRUN_SERVICE_URL
環境變數已定義,則 CSRF_TRUSTED_ORIGINS
和 ALLOWED_HOSTS
設定會使用該變數。雖然定義 ALLOWED_HOSTS
並非必要,但建議您新增此元素,因為 CSRF_TRUSTED_ORIGINS
原本就會使用這個屬性。
因為您需要服務網址,所以您必須等到首次部署之後,才能新增這項設定。
您必須更新服務,才能新增此環境變數。這可以新增至 application_settings 密鑰,或是直接新增為環境變數。
擷取服務網址:
CLOUDRUN_SERVICE_URL=$(gcloud run services describe django-cloudrun \ --platform managed \ --region $REGION \ --format "value(status.url)") echo $CLOUDRUN_SERVICE_URL
在您的 Cloud Run 服務上,將這個值設為環境變數:
gcloud run services update django-cloudrun \ --region $REGION \ --update-env-vars CLOUDRUN_SERVICE_URL=$CLOUDRUN_SERVICE_URL
登入 Django 管理員
如要存取 Django 管理員介面,請將 /admin 附加至服務網址。
現在以「admin」這個使用者名稱登入並使用以下指令擷取密碼:
gcloud secrets versions access latest --secret django_superuser_password && echo ""
10. 開發應用程式
開發應用程式時,您可能會想在本機上進行測試。為此,您必須連線至 Cloud SQL (「正式環境」) 資料庫或本機 (「測試」) 資料庫。
連線至實際工作環境的資料庫
您可以使用 Cloud SQL 驗證 Proxy 連線至 Cloud SQL 執行個體。這個應用程式會從本機電腦連線至資料庫。
安裝 Cloud SQL 驗證 Proxy 後,請按照下列步驟操作:
# 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 --instances=${PROJECT_ID}:${REGION}:myinstance=tcp:5432 # 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
檔案。
建立遷移作業
變更資料庫模型時,您可能需要執行 python manage.py makemigrations
來產生 Django 的遷移檔案。
設定實際工作環境或測試資料庫連線之後,您可以執行這個指令。或者,您也可以指定空白設定,在沒有資料庫的情況下產生遷移檔案:
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 django-cloudrun \ --platform managed \ --region $REGION \ --image ${ARTIFACT_REGISTRY}/myimage
11. 恭喜!
您已成功將複雜的專案部署至 Cloud Run!
- Cloud Run 會自動及水平擴充您的容器映像檔,以處理收到的要求,然後在需求減少時縮減規模。您只需要支付處理要求期間使用的 CPU、記憶體和網路費用。
- Cloud SQL 可讓您佈建自動維護的代管 PostgreSQL 執行個體,並原生整合至許多 Google Cloud 系統中。
- Cloud Storage 可讓您以順暢的方式在 Django 中存取雲端儲存空間。
- Secret Manager 可讓您儲存密鑰,並允許 Google Cloud 的特定部分存取密鑰。
清理
如要避免系統向您的 Google Cloud Platform 帳戶收取您在本教學課程中所用資源的相關費用:
- 在 Cloud 控制台中,前往「管理資源」頁面。
- 在專案清單中,選取您的專案,然後按一下「Delete」(刪除)。
- 在對話方塊中輸入專案 ID,然後按一下「Shut down」(關閉) 即可刪除專案。
瞭解詳情
- Cloud Run 上的 Django:https://cloud.google.com/python/django/run
- 「Hello Cloud Run with Python」:https://codelabs.developers.google.com/codelabs/cloud-run-hello-python3
- 在 Google Cloud 中使用 Python:https://cloud.google.com/python
- Google Cloud Python 用戶端:https://github.com/googleapis/google-cloud-python