在 Azure 中透過 PostgreSQL 部署 Python (Django 或 Flask) Web 應用程式
在本教學課程中,您會將資料驅動的 Python Web 應用程式 (Django 或 Flask) 部署至 Azure App Service 及 Azure Database for PostgreSQL 關聯式資料庫服務。 Azure App Service 在 Linux 伺服器環境中支援 Python。
若要完成本教學課程,您需要:
- 具有有效訂用帳戶的 Azure 帳戶。 如果您沒有 Azure 帳戶,可以建立一個免費帳戶。
- 具有 Flask 開發的 Python 知識或具有 Django 開發的 Python 知識
- 具有有效訂用帳戶的 Azure 帳戶。 如果您沒有 Azure 帳戶,可以建立一個免費帳戶。
- 已安裝 Azure Developer CLI。 您可以遵循 Azure Cloud Shell 的步驟,因為這已安裝 Azure Developer CLI。
- 具有 Flask 開發的 Python 知識或具有 Django 開發的 Python 知識
跳到結尾
安裝 Azure Developer CLI 後,您可以部署本教學課程中顯示的完整設定範例應用程式,並看到這在 Azure 中執行。 只要在空的工作目錄中執行下列命令:
azd auth login
azd init --template msdocs-flask-postgresql-sample-app
azd up
範例應用程式
提供使用 Flask 和 Django 架構的 Python 應用程式範例,以協助您遵循本教學課程。 若要部署應用程式但不在本機執行,請略過此部分。
若要在本機執行應用程式,請確定您已在本機安裝 Python 3.7 或更新版本和 PostgreSQL。 接著,複製範例存放庫的 starter-no-infra
分支,並切換至存放庫根路徑。
git clone -b starter-no-infra https://github.com/Azure-Samples/msdocs-flask-postgresql-sample-app
cd msdocs-flask-postgresql-sample-app
使用 .env.sample 檔案做為指南建立如下所示的 .env 檔案。 將 DBNAME
的值設定為本地 PostgreSQL 執行個體中現有資料庫的名稱。 針對本地 PostgreSQL 執行個體適當地設定 DBHOST
、DBUSER
和 DBPASS
的值。
DBNAME=<database name>
DBHOST=<database-hostname>
DBUSER=<db-user-name>
DBPASS=<db-password>
建立應用程式的虛擬環境:
py -m venv .venv
.venv\scripts\activate
安裝相依性:
pip install -r requirements.txt
使用下列命令執行應用程式範例:
# Run database migration
flask db upgrade
# Run the app at http://127.0.0.1:5000
flask run
1.建立 App Service 和 PostgreSQL
在此步驟中,您會建立 Azure 資源。 本教學課程中使用的步驟會建立一組預設保護資源,其中包含 App Service 和 Azure Database for PostgreSQL。 針對建立程序,您將指定:
- Web 應用程式的 [名稱]。 此名稱會以
https://<app-name>.azurewebsites.net
的形式作為 Web 應用程式 DNS 名稱的一部分。 - 要實際執行應用程式的區域。
- 應用程式的執行階段堆疊。 您可以在此處選取要用於應用程式的 Python 版本。
- 應用程式的主控方案。 這是定價層,其中包含應用程式的一組功能和調整限度。
- 應用程式的 [資源群組]。 資源群組允許您將應用程式所需的所有 Azure 資源分組 (在邏輯容器中)。
登入 Azure 入口網站,遵循下列步驟建立您的 Azure App Service 資源。
第 1 步:在 Azure 入口網站中:
- 在 Azure 入口網站頂端的搜尋列中輸入「Web 應用程式資料庫」。
- 選取 [Marketplace] 標題下標示為 [Web 應用程式 + 資料庫] 的項目。 您也可以直接瀏覽至建立精靈。
第 2 步:在 [建立 Web 應用程式 + 資料庫] 頁面上,填寫表單,如下所示。
- 資源群組 →選取 [新建],並使用名稱 msdocs-python-postgres-tutorial。
- 區域 → 您附近的任何 Azure 區域。
- 名稱 → msdocs-python-postgres-XYZ,其中 XYZ 是任意三個隨機字元。 此名稱在整個 Azure 中必須是唯一的。
- 執行階段堆疊 → Python 3.10。
- 資料庫 → PostgreSQL - 彈性伺服器會依預設選取做為資料庫引擎。 伺服器名稱和資料庫名稱預設也會設定為適當的值。
- 主控方案 → 基本。 當一切就緒時,您可以在之後擴大至生產定價層。
- 選取 [檢閱 + 建立]。
- 驗證完成時,選取 [建立]。
步驟 3:部署需要數分鐘的時間才能完成。 在部署完成時,選取 [前往資源] 按鈕。 系統會將您直接帶至 App Service 應用程式,但會建立下列資源:
- 資源群組 → 所有已建立資源的容器。
- App Service 計畫 → 定義 App Service 的計算資源。 系統會建立基本層中的 Linux 方案。
- App Service → 代表您的應用程式,並在 App Service 方案中執行。
- 虛擬網路 → 與 App Service 應用程式整合,並隔離後端網路流量。
- Azure Database for PostgreSQL 彈性伺服器 → 只能從虛擬網路內部存取。 系統會為您在伺服器上建立資料庫和使用者。
- 私人 DNS 區域 → 啟用虛擬網路中 PostgreSQL 伺服器的 DNS 解析。
2.保護聯機秘密
建立精靈已為您產生資料庫連線字串做為 應用程式設定。 不過,安全性最佳做法是將祕密完全從 App Service 中移出。 您可以使用 Service Connector 的協助,將秘密移至密鑰保存庫,並將應用程式設定變更為 金鑰保存庫 參考。
步驟 1:擷取現有的 連接字串
- 在 App Service 頁面的左側功能表中,選取 [ 設定 > 環境變數]。
- 選取 [AZURE_POSTGRESQL_CONNECTIONSTRING]。
- 在 [新增/編輯應用程式設定] 的 [值] 欄位中,尋找位於字串結尾的 password= 部分。
- 複製 Password= 後面的密碼字串,以供後續使用。 此應用程式設定可讓您連線到私人端點後方所保護的Postgres資料庫。 不過,秘密會直接儲存在 App Service 應用程式中,這不是最好的方式。 您要變更此設定。
步驟 2:建立金鑰保存庫以安全地管理秘密
- 在頂端搜尋列中,輸入 "key vault",然後選取 [Marketplace] > [Key Vault]。
- 在 [資源群組] 中,選取 msdocs-python-postgres-tutorial。
- 在 [金鑰保存庫名稱] 中,輸入只包含字母和數字的名稱。
- 在 [區域] 中,將它設定為與資源群組相同的位置。
步驟 3:使用私人端點保護金鑰保存庫
- 選取 [網路] 索引標籤。
- 取消選取 [啟用公用存取]。
- 選取 [建立私人端點]。
- 在 [資源群組] 中,選取 msdocs-python-postgres-tutorial。
- 在 [ 名稱] 中,輸入只包含字母和數位的私人端點名稱。
- 在 [區域] 中,將它設定為與資源群組相同的位置。
- 在對話方塊的 [位置] 中,選取與 App Service 應用程式相同的位置。
- 在 [資源群組] 中,選取 msdocs-python-postgres-tutorial。
- 在 [ 名稱] 中,輸入 msdocs-python-postgres-XYZVaultEndpoint。
- 在 [虛擬網络] 中,選取 msdocs-python-postgres-XYZVnet。
- 在 Subnet 中, msdocs-python-postgres-XYZSubnet。
- 選取 [確定]。
- 選取 [檢閱 + 建立],然後選取 [建立]。 等候金鑰保存庫部署完成。 您應該會看到「您的部署已完成」。
步驟 4:設定服務連接器
- 在頂端搜尋列中,輸入 msdocs-python-postgres,然後選取名為 msdocs-python-postgres-XYZ 的 App Service 資源。
- 在 App Service 頁面的左側功能表中,選取 [設定 > 服務連接器]。 已經有連接器,這是為您建立的應用程式建立精靈。
- 選取連接器旁的核取方塊,然後選取 [編輯]。
- 在 [基本] 索引標籤的 [PostgreSQL 資料庫] 底下,選取已建立的 PostgreSQL 資料庫。
- 選取 [驗證] 索引標籤。
- 在 [密碼] 中,貼上您先前複製的密碼。
- 選取 [在 Key Vault 中儲存秘密]。
- 在 [金鑰保存庫連線] 底下,選取 [新建]。 [建立連線] 對話方塊會在編輯對話方塊的頂端開啟。
步驟 5:建立 金鑰保存庫 連線
- 在 [建立 金鑰保存庫 連線] 對話方塊的 [金鑰保存庫] 中,選取您稍早建立的密鑰保存庫。
- 選取 [檢閱 + 建立] 。
- 驗證完成時,選取 [建立]。
步驟 6:完成服務連接器設定
- 您回到 defaultConnector 的編輯對話框中。 在 [驗證] 索引標籤中,等候建立金鑰保存庫連接器。 完成時,[Key Vault 連線] 下拉式清單會自動加以選取。
- 選取 [下一步:網路]。
- 選取 [儲存]。 等到 [更新成功] 通知出現為止。
步驟 7:確認 金鑰保存庫 整合
- 從左側功能表中,再次選取 [ 設定 > 環境變數 ]。
- 在AZURE_POSTGRESQL_CONNECTIONSTRING旁,選取 [顯示值]。 該值應該是
@Microsoft.KeyVault(...)
,這表示它是金鑰保存庫參考,因為現在已在金鑰保存庫中管理秘密。
總而言之,從 App Service 環境變數擷取 PostgreSQL 連接字串、使用私人存取建立 Azure 金鑰保存庫 來保護秘密管理,以及更新服務連接器以將密碼儲存在密鑰保存庫中的程式。 App Service 應用程式和金鑰保存庫之間的安全連線是使用系統指派的受控識別建立的,而且已確認 連接字串 使用 金鑰保存庫 參考來驗證設定。
有問題嗎? 查看疑難排解區段。
3.部署範例程式碼
在此步驟中,您將使用 GitHub Actions 來設定 GitHub 部署。 這只是部署至 App Service 的許多方式之一,但也是在部署程序中持續整合的絕佳方式。 根據預設,您 GitHub 存放庫的每個 git push
都會開始建置和部署動作。
第 1 步:在新的瀏覽器視窗中:
- 登入您的 GitHub 帳戶。
- 瀏覽至 https://github.com/Azure-Samples/msdocs-flask-postgresql-sample-app。
- 請選取分叉。
- 選取 [建立派生]。
步驟 2:在 [GitHub] 頁面中,按下 .
鍵,在瀏覽器中開啟 Visual Studio Code。
第 3 步:在瀏覽器中的 Visual Studio Code,在總管中開啟 azureproject/production.py。 查看生產環境中所使用的環境變數,包括您在設定頁面中看到的應用程式設定。
第 4 步:回到 [App Service] 頁面的左側功能表中,選取 [部署中心]。
第 5 步:在 [部署中心] 頁面上:
- 在 [來源] 中,選取 [GitHub]。 根據預設,系統會選取 GitHub Actions 作為組建提供者。
- 登入您的 GitHub 帳戶,並遵循提示來授權 Azure。
- 在 [組織] 中,選取您的帳戶。
- 在 [存放庫] 中,選取 msdocs-flask-postgresql-sample-app。
- 在 [分支] 中,選取 [main]。
- 將選擇預設選項保留為 [新增工作流程]。
- 在 [驗證類型]下,選取 [使用者指派的身分識別]。
- 在最上層的功能表中,選取 [儲存]。 App Service 會將工作流程檔案認可至
.github/workflows
目錄中選擇的 GitHub 存放庫。
第 6 步:在 [部署中心] 頁面上:
- 選取 [記錄] 。 已啟動部署執行。
- 在部署執行的記錄項目中,選取 [建置/部署記錄]。
第 7 步:您已前往 GitHub 存放庫,並看到 GitHub 動作正在執行。 工作流程檔案會定義兩個不同的階段:建置和部署。 等候 GitHub 執行到顯示 [完成] 狀態。 需要約 5 分鐘的時間。
有問題嗎? 請查看疑難排解指南。
4.產生資料庫結構描述
透過受虛擬網路保護的 PostgreSQL 資料庫,執行 Flask 資料庫移轉最簡單的方式是在 SSH 工作階段搭配 App Service 容器中。
第 1 步:在 App Service 頁面上的左側功能表,
- 選取 [SSH]。
- 選取 [執行]。
第 2 步:在 SSH 終端機中,執行 flask db upgrade
。 如果成功,App Service 已成功連線至資料庫。
只有 /home
中檔案的變更才能在應用程式重新開機之後保存。 /home
以外的變更不會保存。
5.瀏覽至應用程式
第 1 步:在 [App Service] 頁面中:
- 從左側功能表中選取 [概觀]。
- 選取應用程式的 URL。 您也可以直接瀏覽至
https://<app-name>.azurewebsites.net
。
第 2 步: 將幾個餐廳新增至清單中。 恭喜,您正在 Azure App Service 中執行 Web 應用程式,並安全地連線至 PostgreSQL 的適用於 PostgreSQL 的 Azure 資料庫。
6.資料流診斷記錄
Azure App Service 會擷取輸出到主控台的所有訊息,以協助您診斷應用程式的問題。 如下所示,樣本應用程式包含可示範這項功能的 print()
陳述式。
@app.route('/', methods=['GET'])
def index():
print('Request for index page received')
restaurants = Restaurant.query.all()
return render_template('index.html', restaurants=restaurants)
第 1 步:在 [App Service] 頁面中:
- 從左側功能表中,選取 [App Service 記錄]。
- 在 [應用程式記錄] 下,選取 [檔案系統]。
- 在最上層的功能表中,選取 [儲存]。
步驟 2:從左側功能表中,選取 [記錄串流]。 您會看到應用程式的記錄,包括平台記錄和來自容器內的記錄。
深入了解如何在設定適用於 Python 應用程式的 Azure 監視器系列中記錄 Python 應用程式。
7.清除資源
完成後,您可以刪除資源群組,以從 Azure 訂用帳戶中刪除所有資源。
步驟 1:在 Azure 入口網站頂端的搜尋列中:
- 輸入資源群組名稱。
- 選取資源群組。
步驟 2:在資源群組頁面中,選取 [刪除資源群組]。
步驟 3:
- 輸入您確認要刪除的資源群組名稱。
- 選取 [刪除]。
1.建立 Azure 資源並部署範例應用程式
在此步驟中,您會建立 Azure 資源,並將範例應用程式部署至 Linux 上的 App Service。 本教學課程中使用的步驟會建立一組預設保護資源,其中包含 App Service 和 Azure Database for PostgreSQL。
如果您尚未這麼做,請在本機終端機中複製範例存放庫的
starter-no-infra
分支。git clone -b starter-no-infra https://github.com/Azure-Samples/msdocs-flask-postgresql-sample-app cd msdocs-flask-postgresql-sample-app
此複製的分支是您起點。 它包含簡單的資料磁碟驅動器 Flask 應用程式。
從存放庫根路徑中執行
azd init
。azd init --template python-app-service-postgresql-infra
出現提示時,請提供下列答案:
問題 回答 目前的目錄不是空的。 您是否要在「<您的目錄>」初始化專案? Y 您要對這些檔案執行什麼動作? 維持現有的檔案不變 輸入新的環境名稱 輸入唯一名稱。 azd 範本會使用此名稱作為 Azure 中 Web 應用程式的 DNS 名稱的一部分 ( <app-name>.azurewebsites.net
)。 允許英數字元與連字號。執行
azd up
命令來佈建必要的 Azure 資源,並部署應用程式程式代碼。 如果您尚未登入 Azure,瀏覽器將啟動並要求您登入。azd up
命令也會提示您選取要部署的訂用帳戶和位置。azd up
azd up
命令可能需要幾分鐘才能完成。 這也會編譯及部署您的應用程式程序代碼,但稍後會修改程序代碼以使用 App Service。 執行時,命令會提供佈建和部署程式的相關資訊,包括 Azure 中部署的連結。 完成時,命令也會顯示部署應用程式的連結。此 azd 範本包含檔案 (azure.yaml 和 infra directory),其預設會使用下列 Azure 資源產生安全架構:
- 資源群組 → 所有已建立資源的容器。
- App Service 計畫 → 定義 App Service 的計算資源。 會指定B1層中的 Linux 方案。
- App Service → 代表您的應用程式,並在 App Service 方案中執行。
- 虛擬網路 → 與 App Service 應用程式整合,並隔離後端網路流量。
- Azure Database for PostgreSQL 彈性伺服器 → 只能從虛擬網路內部存取。 系統會為您在伺服器上建立資料庫和使用者。
- 私人 DNS 區域 → 啟用虛擬網路中 PostgreSQL 伺服器的 DNS 解析。
- Log Analytics 工作區 → 做為應用程式傳送記錄的目標容器,您也可以在其中查詢記錄。
2.使用資料庫連結字串
您使用的 azd 範本已為您產生連線變數作為應用程式設定,並輸出至終端機以方便起見。 應用程式設定是將連線秘密保留在程式碼存放庫外部的一個方法。
在 azd 輸出中,尋找應用程式設定,並尋找設定
AZURE_POSTGRESQL_CONNECTIONSTRING
和AZURE_REDIS_CONNECTIONSTRING
。 為了保護祕密安全,只會顯示設定名稱。 在 azd 輸出中看起來像這樣:App Service app has the following settings: - AZURE_POSTGRESQL_CONNECTIONSTRING - AZURE_REDIS_CONNECTIONSTRING - FLASK_DEBUG - SCM_DO_BUILD_DURING_DEPLOYMENT - SECRET_KEY
AZURE_POSTGRESQL_CONNECTIONSTRING
包含 Azure 中 Postgres 資料庫的連接字串,AZURE_REDIS_CONNECTIONSTRING
包含 Azure 中 Redis 快取的連接字串。 您必須使用程式代碼來連線。 開啟 azureproject/production.py,取消註解下列幾行,然後儲存檔案:conn_str = os.environ['AZURE_POSTGRESQL_CONNECTIONSTRING'] conn_str_params = {pair.split('=')[0]: pair.split('=')[1] for pair in conn_str.split(' ')} DATABASE_URI = 'postgresql+psycopg2://{dbuser}:{dbpass}@{dbhost}/{dbname}'.format( dbuser=conn_str_params['user'], dbpass=conn_str_params['password'], dbhost=conn_str_params['host'], dbname=conn_str_params['dbname'] )
您的應用程式程式代碼現在已設定為連線到 Azure 中的 PostgreSQL 資料庫。 如果您想要,請開啟
app.py
,並檢視如何使用DATABASE_URI
環境變數。在終端機中,執行
azd deploy
。azd deploy
4.產生資料庫結構描述
透過受虛擬網路保護的 PostgreSQL 資料庫,執行 Flask 資料庫移轉最簡單的方式是在 SSH 工作階段搭配 App Service 容器中。
在 azd 輸出中,尋找 SSH 工作階段的 URL,並在瀏覽器中導覽至目標。 輸出中看起來像這樣:
Open SSH session to App Service container at: https://<app-name>.scm.azurewebsites.net/webssh/host
在 SSH 終端機中,執行
flask db upgrade
。 如果成功,App Service 已成功連線至資料庫。注意
只有
/home
中檔案的變更才能在應用程式重新開機之後保存。/home
以外的變更不會保存。
5.瀏覽至應用程式
在 azd 輸出中,尋找您應用程式的 URL,並在瀏覽器中導覽至目標。 AZD 輸出中 URL 看起來像這樣:
Deploying services (azd deploy) (✓) Done: Deploying service web - Endpoint: https://<app-name>.azurewebsites.net/
將幾個餐廳新增至清單中。
恭喜,您正在 Azure App Service 中執行 Web 應用程式,並安全地連線至 PostgreSQL 的適用於 PostgreSQL 的 Azure 資料庫。
6.資料流診斷記錄
Azure App Service 會擷取主控台記錄,以協助您診斷應用程式的問題。 為了方便起見,azd 範本已啟用本機檔案系統記錄,並將期傳送至 Log Analytics 工作區。
如下方片段所示,樣本應用程式包含可示範這項功能的 print()
陳述式。
@app.route('/', methods=['GET'])
def index():
print('Request for index page received')
restaurants = Restaurant.query.all()
return render_template('index.html', restaurants=restaurants)
在 azd 輸出中,尋找串流 App Service 記錄的連結,並在瀏覽器導覽至目標。 azd 輸出中連結看起來像這樣:
Stream App Service logs at: https://portal.azure.com/#@/resource/subscriptions/<subscription-guid>/resourceGroups/<group-name>/providers/Microsoft.Web/sites/<app-name>/logStream
深入了解如何在設定適用於 Python 應用程式的 Azure 監視器系列中記錄 Python 應用程式。
7.清除資源
若要刪除目前部署環境中的所有 Azure 資源,請執行 azd down
。
azd down
疑難排解
以下列出您在嘗試完成本教學課程時可能會遇到的問題,以及解決這些問題的步驟。
我無法連線至 SSH 工作階段
如果您無法連線至 SSH 工作階段,表示應用程式本身無法啟動。 如需詳細資訊,請查看診斷記錄。 例如,如果您看到類似 KeyError: 'AZURE_POSTGRESQL_CONNECTIONSTRING'
的錯誤,這可能表示環境變數遺失 (您可能已移除應用程式設定)。
我在執行資料庫移轉時收到錯誤
如果您遇到與連線至資料庫相關的任何錯誤,請檢查應用程式設定 (AZURE_POSTGRESQL_CONNECTIONSTRING
) 是否遭到變更。 若未完成那份連結字串,移轉命令就無法與資料庫通訊。
常見問題集
- 這設定會產生多少費用?
- 如何使用其他工具連線至虛擬網路後方受保護的 PostgreSQL 伺服器?
- 本機應用程式開發如何與 GitHub Actions 搭配運作?
- 如何設定 Django 範例以在 Azure App Service 上執行?
這設定會產生多少費用?
建立資源的定價如下:
- App Service 方案是在基本層中建立,並可擴大或縮小。 請參閱 App Service 定價。
- PostgreSQL 彈性伺服器是在最低的高載層 Standard_B1ms 中建立,搭配最少的儲存體大小,儲存體大小可以相應增加或減少。 請參閱 Azure PostgreSQL Database 定價。
- 除非您設定額外的功能 (例如對等互連),否則虛擬網路不會產生費用。 請參閱 Azure 虛擬網路定價。
- 私人 DNS 區域會產生少量費用。 請參閱 Azure DNS 定價。
如何使用其他工具連線至虛擬網路後方受保護的 PostgreSQL 伺服器?
- 若要從命令列工具進行基本存取,您可以從應用程式的 SSH 終端機執行
psql
。 - 若要從桌面工具連線,您的電腦必須位於虛擬網路內。 例如,該電腦可以是連線到其中一個子網路的 Azure VM,或內部部署網路中具有與 Azure 虛擬網路站對站 VPN 連線的電腦。
- 您也可以將 Azure Cloud Shell 與虛擬網路整合。
本機應用程式開發如何與 GitHub Actions 搭配運作?
使用 App Service 自動產生的工作流程檔案為例,每個 git push
都會開始執行新的組建和部署。 從 GitHub 存放庫的本機複本,並將所需的更新推送至 GitHub。 例如:
git add .
git commit -m "<some-message>"
git push origin main
如何設定 Django 範例以在 Azure App Service 上執行?
Django 範例應用程式會設定在 azureproject/production.py 檔案中的設定,使其可在 Azure App Service 中執行。 這些變更常見於將 Django 部署到生產環境時,而非 App Service 特有。
Django 會驗證連入要求中的 HTTP_HOST 標頭。 範例程式碼使用 App Service 中的
WEBSITE_HOSTNAME
環境變數,將應用程式的網域名稱新增至 Django 的 ALLOWED_HOSTS 設定。# Configure the domain name using the environment variable # that Azure automatically creates for us. ALLOWED_HOSTS = [os.environ['WEBSITE_HOSTNAME']] if 'WEBSITE_HOSTNAME' in os.environ else []
Django 不支援在生產環境中提供靜態檔案。 在本教學課程中,您會使用 WhiteNoise 來提供檔案。 已安裝 WhiteNoise 套件及 requirements.txt,其中介軟體已新增至清單。
# WhiteNoise configuration MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # Add whitenoise middleware after the security middleware 'whitenoise.middleware.WhiteNoiseMiddleware',
然後,會根據 Django 文件設定靜態檔案設定。
SESSION_ENGINE = "django.contrib.sessions.backends.cache" STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
如需詳細資訊,請參閱 Django 應用程式的生產設定。
下一步
前進到下一個教學課程,了解如何使用自訂網域和憑證保護您的應用程式。
了解 App Service 如何執行 Python 應用程式: