人事行政總處事求人開放資料版網站是我多年前的一個 side project,當時是把整個網站放在 AWS EC2 上,底層的 infra 如 Apache web server 以及 Django 的 WSGI 設定等都是自己來,承蒙大家的關照,多年來網站的 DAU (每日使用者) 一直都滿穩定的。去年剛好有個空檔,就把我一直想調整的留言顯示介面改好了,同時也順便升級網站後端,並且搬到 Azure PaaS 上。總結來說這次的更新有:
- 把 Django 版本從 1.8 換到 4.2 LTS
- 把網站從 AWS EC2 (IaaS, 自架 web server),搬到 Azure Web App (PaaS);好處是直接支援 HTTPS 以及自訂網域,部署也相對容易
- 把資料庫從 SQLite 移到 Azure MySQL
以下是網站升版過程的一些技術筆記。網站本身也是開源的,對程式碼有興趣的可以直接參考 GitHub Repo
Django 版本從 1.8 換到 4.2 LTS
這部份並不困難,就是把專案程式碼在本機直接改用 Django 4.2 版執行,過程中會看到各式不相容或過期的程式碼錯誤/警告,把它們都改掉,直到網站可以成功在本機跑起來即可。
改用 Azure Web App
微軟這篇手把手的教學說明了如何把 Django 網站部署到 Azure Web App 上。相對於部署在自己的主機上,特別要注意的地方有:
- 需額外安裝
whitenoise套件 - 在 Django 預設的
settings.py以外,需另外創建一個設定檔azure.py,並且- 在 MIDDLEWARE 變數內新增
whitenoise.middleware.WhiteNoiseMiddleware - 設定靜態檔案儲存位置:
STATICFILES_STORAGE = ('whitenoise.storage.CompressedStaticFilesStorage') - 對於
ALLOWED_HOSTS及CSRF_TRUSTED_ORIGINS變數,至少要加上os.environ['WEBSITE_HOSTNAME'];如果你還有自訂網域,也要記得加上
- 在 MIDDLEWARE 變數內新增
把網站移到 Azure Web App 上後,自動部署 (with GitHub Action) 與自訂網域等設定就變得簡單許多,不需要再煩惱網站主機的各項設定 (如 http.conf 或如何支援 HTTPS 等)
資料庫從 SQLite 移到 MySQL
這部份是花最多時間的,這篇文章滿清楚地說明了資料轉移的四個步驟:
- 把資料用
python manage.py dumpdatadump 出來 - 建立 MySQL 資料庫及資料表
- 更改 Django 設定檔中
DATABASES變數的值,改指向 MySQL engine - 把第一步的資料用
python manage.py loaddata匯入新的資料表中
我的資料內容包含了 4 bytes 的 UTF-8 內容及一些亂碼,這些不符合資料欄位定義的內容以前都被 SqLite 資料庫默默的吞下去且儲存起來,但在 MySQL 中會報錯,資料匯入過程中會看到類似以下的錯誤訊息:
(1366, "Incorrect string value: '\\\\xF0\\\\x9F\\\\x98\\\\x80\\\\xF0\\\\x9F...' for column 'name' at row 1")
這是因為 MySQL 的 UTF-8 只允許 3 個位元組的資料,要修正這個錯誤,必須在一開始創造資料庫及資料表的時候,就使用 utf8mb4 的 Character set 以及 utf8mb4_general_ci 的 Collation. 同時在 Django 的 DATABASES 變數中要多加一個 option:
'OPTIONS': {'charset': 'utf8mb4'}
最後,在資料轉移時,我並不需要 Django admin 的資料,而只需要我的 App 資料。使用如下指令就可以只 dump 特定 App 或 Model 的資料 (細節可見這篇問答)
manage.py dumpdata myapp1 myapp2.my_model
網站是開源的,對更多細節有興趣的可以到 GitHub 上看程式碼: