部署 Django 2 至 Google App Engine 第二代標準環境教學

Django 是知名的 python 網站應用程式框架,功能完整、社群活耀、提供開發者良好的基石,知名的應用程式如:Instagrm、Spotify、Youtube、Dropbox 都採用 Python + Django。

透過 Google Cloud Platform 託管 Django 的方法可分為:VM(虛擬主機)、Container(容器)、Serverless(無伺服器),本篇教學是 Serverless,使用最新的 App Engine 第二代標準環境,把所有主機維運的重擔全部交給 Google。開發與部署都在 Cloud Shell 中完成,只需瀏覽器就可以學習,也適合想學習 Django 成為後端軟體工程師的人。

必要知識

您必須要具備以下基本知識才能完成本篇教學

  1. 了解如何建立與管理 GCP 專案:
    https://cloud.google.com/resource-manager/docs/creating-managing-projects
  2. 了解 Cloud Shell 基本操作:
    https://cloud.google.com/shell/docs/starting-cloud-shell
  3. 了解基本的 linux 指令。

以下非必要,但如果有更好

  1. 了解 python 語法與開發程序。
  2. 具有 Django、MVC 架構概念。

為什麼選擇部署在 Goolge App Engine 第二代標準環境

Google App Engine 是 Google Cloud Serverless 雲端服務,讓開發者專注程式而非維運主機,共有三種環境:標準環境(第一代、第二代)與彈性環境。最新的第二代標準環境是具有容器特性的沙盒,融合第一代標準環境與彈性環境的優點:

  1. 開發者可以用慣用的 python 開發程序。
  2. 幾乎瞬間的擴展以應付瞬間的大流量,彈性環境則適合流量平穩的網站。
  3. 每日免費額度,流量不大幾乎不用錢。
  4. 自訂網址和免費代管的 SSL 憑證提供 HTTPS 連線。
  5. 檔案系統與網路存取等,詳情:https://cloud.google.com/appengine/docs/standard/appengine-generation

另外,第一代標準環境支援 python 2.7,僅適用 Django 1.11。第二代標準環境支援 pyhton 3.7,可以使用最新的 Django 版本(本文撰寫時為 2.1.2 版)。

區域選擇

同時考慮 App Engine 與 第二代 Cloud SQL 支援的區域,本篇選擇 asia-east2 (香港)。

為了降低延遲,建議 App Engine 與 Cloud SQL 選同一區域,以下是服務支援區域查詢網址:
App Engine:https://cloud.google.com/appengine/docs/locations
Cloud SQL:https://cloud.google.com/sql/docs/mysql/locations

開始前,建立一個全新專案並啟動 Cloud Shell

startcloudshell1

startcloudshell2

建立 MySQL 資料庫

我們使用 MySQL 作為本範例的資料庫後端。在 Cloud SQL 建立一個 MySQL 實例,命名為 django,在 Cloud Shell 下輸入:

gcloud sql instances create django \
     --activation-policy=ALWAYS \
     --region=asia-east2 \
     --tier=db-n1-standard-1

測試用途可以改用 db-f1-micro 或 db-g1-small 取代 db-n1-standard-1 以減少支出,正式環境則不建議。接著建立資料庫,命名為 djangodb

$ gcloud sql databases create djangodb --instance django

設定 root 密碼:

$ gcloud sql users set-password root \
     --host=% \
     --instance django \
     --password=p@ssw0rd # 請修改為自己的密碼

為開發環境準備 Cloud SQL Proxy

為了要在 Cloud Shell 中連線到上述建立的 MySQL 資料庫,Google 提供一個 Cloud SQL Proxy 程式提供簡單而且安全的連線方式。

首先,新增一個連線階段分頁:

add_session
開啟一個新的連線階段分頁

下載 cloud_sql_proxy 程式:

$ wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
$ chmod +x cloud_sql_proxy

之後啟動指如下:(請修改 YOUR_PROJECT_ID 為您的專案ID)

$ cloud_sql_proxy -instances=YOUR_PROJECT_ID:asia-east2:django=tcp:3306

出現 Ready for new connections 提示則代表已準備就緒。讓這個分頁保持開啟,回到原本的連現階段分頁,繼續接下來的教學。

詳細 Cloud SQL Proxy 請參考此說明頁面:https://cloud.google.com/sql/docs/mysql/sql-proxy

建立 App Engine 服務

為專案啟用 App Engine 服務,只能執行一次,區域必須慎選,無法再修改。建議要與資料庫同一個區域以降低延遲。

$ gcloud app create --region=asia-east2

建立 pyhton 虛擬環境

建立虛擬環境,指定 pyhton3,目錄命名為 django2-gae2

$ virtualenv -p python3 django2-gae2

啟動虛擬環境,並且在這個環境中安裝 Django 與 PyMySQL 套件

$ source django2-gae2/bin/activate
(django2-gae2) $ pip install Django
(django2-gae2) $ pip install PyMySQL

確認 Django 模組已經安裝正確版本

(django2-gae2) $ python -m django --version
2.1.2

開始建立 Django 專案

使用 django-admin 指令建立一個全新 Django 專案,命名為 mysite,並切換到專案目錄

(django2-gae2) $ django-admin startproject mysite
(django2-gae2) $ cd mysite
(django2-gae2) ~/mysite $

接下來,需要建立與修改檔案,可用你熟悉 vim 等文字編輯指令,或更簡單的方法是透過  Cloud Shell 提供的線上編輯器:

code editor
開啟文字編輯器

Cloud Shell  Editor.png

在專案目錄下建立一個 app.yaml 檔,內容為:

runtime: python37

handlers:
- url: /static
  static_dir: static/

- url: /.*
  script: auto

針對 Python 3.7 的 app.yaml 設定參考頁面: https://cloud.google.com/appengine/docs/standard/python3/config/appref

在專案目錄下建立一個 main.py 檔,內容為:

from mysite.wsgi import application
app = application

App Engine 預設會搜尋根目錄下的 main.py 檔案中的 app 變數,視為 WSGI 相容物件,也就 Django 網站程式的介面。

修改 Django 專案設定檔 mysite/settings.py

# 安全提醒!App Engine 有足夠的安全可以這樣設定,如果採用別的環境請謹慎設定。
ALLOWED_HOSTS = ['*']
 .
 .
 .
# 註解原本 DATABASES 定義
# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.sqlite3',
#         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#     }
# }
import pymysql
pymysql.install_as_MySQLdb()
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'djangodb',
        'USER': 'root',
        'PASSWORD': 'p@ssw0rd', #修改為您的密碼
        'PORT': '3306',
    }
}
DATABASES['default']['HOST'] = '/cloudsql/YOUR_PROJECT_ID:asia-east2:django'
if os.getenv('GAE_APPLICATION', None):
    pass
else:
    # 開發環境中透過 Cloud SQL Proxy 連線到資料庫
    DATABASES['default']['HOST'] = '127.0.0.1'
 .
 .
 .
# 加入這個變數,指定靜態媒體檔目錄
STATIC_ROOT = 'static'

執行到這,專案的檔案目錄結構會像這樣:

mysite/
    app.yaml
    main.py
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

再下幾個指令就完成了,初始化資料庫:

(django2-gae2) ~/mysite $ python manage.py makemigrations
(django2-gae2) ~/mysite $ python manage.py migrate

你可以在 Cloud SQL Proxy 分頁看到有新的連線進來的提示訊息

資料庫管理是 Django 一大重點,開發者只需要定義 Model,其他就交給 Django。如果Model 有變動,例如:字串長度增加或增加一個屬性,Django 都會自動幫你『遷移』。

建立 Djanog admin 第一個管理員:

(django2-gae2) ~/mysite $ python manage.py createsuperuser

蒐集靜態媒體檔案到 ‘static’ 這個目錄:

(django2-gae2) ~/mysite $ python manage.py collectstatic

這個指令會參考上述 settings.py 中的 STATIC_ROOT 的值,同時 app.yaml 也指定 /static 對應的靜態檔案目錄,讓 App Engine 來服務靜態檔案。

啟動開發伺服器

(django2-gae2) ~/mysite $ python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
October 27, 2018 - 17:07:02
Django version 2.1.2, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/ #點擊此連結瀏覽開發網站
Quit the server with CONTROL-C.

開啟頁面後會看到預設的 Django 頁面,Django Admin 網址在 /admin/ 這個路徑下登入。如果你是 Django 的新手,接下來可以按照官方教學完成經典的 Polls 投票 app:https://docs.djangoproject.com/en/2.1/intro/tutorial01/#creating-the-polls-app

部署應用程式

(django2-gae2) ~/mysite $ pip freeze > requirements.txt
(django2-gae2) ~/mysite $ gcloud app deploy

如果一切順利,你的網站就在這個網址中運作 https://YOUR_PROJECT_ID.appspot.com。

結語

本編教學展示了以慣用的 python 開發程序部署 Django 到 App Engine 第二代標準環境。Serverless 雲端服務、功能完整的 Django 框架和豐富的 python 套件成為支撐您的應用程式的強大基石。