Django 教程第 11 部分:將 Django 部署到生產環境
現在你已經建立(並測試)了一個很棒的 LocalLibrary 網站,你將希望把它安裝到一個公共的 Web 伺服器上,以便圖書館工作人員和成員可以透過網際網路訪問它。本文概述瞭如何找到一個主機來部署你的網站,以及你需要做些什麼才能讓你的網站準備好投入生產。
| 先決條件 | 完成所有之前的教程主題,包括 Django 教程第 10 部分:測試 Django Web 應用程式。 |
|---|---|
| 目標 | 瞭解在哪裡以及如何將 Django 應用程式部署到生產環境。 |
概述
網站完成後(或“足夠”完成以開始公開測試),你需要將其託管在比個人開發計算機更公開、更易訪問的地方。
到目前為止,你一直在開發環境中工作,使用 Django 開發 Web 伺服器將你的網站共享到本地瀏覽器/網路,並使用(不安全的)開發設定執行你的網站,這些設定會公開除錯和其他私有資訊。在你可以將網站託管到外部之前,你首先需要
- 對你的專案設定進行一些更改。
- 選擇一個環境來託管 Django 應用程式。
- 選擇一個環境來託管任何靜態檔案。
- 為你的網站設定一個生產級基礎設施。
本教程提供了一些關於選擇託管網站的選項的指導,簡要概述了你需要做些什麼才能讓你的 Django 應用程式準備好投入生產,以及將 LocalLibrary 網站安裝到 Railway 雲託管服務的示例。
什麼是生產環境?
生產環境是伺服器計算機提供的環境,你將在其中執行你的網站以供外部使用。該環境包括
- 執行網站的計算機硬體。
- 作業系統(例如 Linux、Windows)。
- 在你的網站之上編寫的程式語言執行時和框架庫。
- 用於提供頁面和其他內容的 Web 伺服器(例如 Nginx、Apache)。
- 將“動態”請求在你的 Django 網站和 Web 伺服器之間傳遞的應用程式伺服器。
- 你的網站依賴的資料庫。
注意:取決於你的生產環境的配置方式,你可能還需要反向代理、負載均衡器等等。
伺服器計算機可以位於你的場所並透過快速連結連線到網際網路,但使用位於“雲”中的計算機更為常見。這實際上意味著你的程式碼是在你的託管公司的資料中心(或可能是“虛擬”計算機)中的某些遠端計算機上執行的。遠端伺服器通常會提供一定級別的計算資源(CPU、RAM、儲存記憶體等)和網際網路連線,並收取一定的費用。
這種遠端可訪問的計算/網路硬體被稱為基礎設施即服務 (IaaS)。許多 IaaS 供應商提供預安裝特定作業系統的選項,你必須在該作業系統上安裝生產環境的其他元件。其他供應商允許你選擇功能更全面的環境,可能包括完整的 Django 和 Web 伺服器設定。
注意:預構建的環境可以使你的網站設定非常容易,因為它們減少了配置,但可用的選項可能會限制你使用不熟悉的伺服器(或其他元件),並且可能基於舊版本的 OS。通常,最好自己安裝元件,這樣你就可以獲得你想要的元件,並且當你需要升級系統的一部分時,你就會知道從哪裡開始!
其他託管提供商在平臺即服務 (PaaS) 產品中支援 Django。在這種型別的託管中,你不需要擔心你的大部分生產環境(Web 伺服器、應用程式伺服器、負載均衡器),因為主機平臺會為你處理這些環境——以及你需要做的大部分事情才能擴充套件你的應用程式。這使得部署非常容易,因為你只需要專注於你的 Web 應用程式,而無需關注其他伺服器基礎設施。
一些開發人員會選擇 IaaS 提供的更高的靈活性,而不是 PaaS,而另一些開發人員則會欣賞 PaaS 減少的維護開銷和更輕鬆的擴充套件。在開始時,在 PaaS 系統上設定你的網站要容易得多,因此我們將在本教程中執行此操作。
注意:如果你選擇了一個 Python/Django 友好的託管提供商,他們應該提供有關如何使用 Web 伺服器、應用程式伺服器、反向代理等的不同配置設定 Django 網站的說明。(如果你選擇了一個 PaaS,這將無關緊要)。例如,在 Digital Ocean Django 社群文件 中,有許多針對各種配置的分步指南。
選擇託管提供商
許多託管提供商都以積極支援或與 Django 協同工作而聞名,包括:Heroku、Digital Ocean、Railway、Python Anywhere、Amazon Web Services、Azure、Google Cloud、Hetzner 和 Vultr Cloud Compute——僅舉幾例。這些供應商提供不同型別的環境(IaaS、PaaS)以及不同價格的不同級別的計算和網路資源。
在選擇主機時需要考慮的一些事項
- 你的網站可能有多繁忙,以及滿足這一需求所需的成本和計算資源。
- 水平擴充套件(新增更多機器)和垂直擴充套件(升級到更強大的機器)的支援級別以及這樣做的成本。
- 供應商擁有資料中心的位置,以及訪問速度最快的區域。
- 主機的歷史正常執行時間和停機時間效能。
- 用於管理網站的工具——它們是否易於使用,以及它們是否安全(例如 SFTP 與 FTP)。
- 用於監控你的伺服器的內建框架。
- 已知的限制。某些主機會故意阻止某些服務(例如電子郵件)。其他主機只提供某些價格級別的“直播時間”,或只提供少量儲存空間。
- 額外優勢。一些供應商會提供免費的域名和對 TLS 證書的支援,否則你需要付費才能獲得這些證書。
- 你依賴的“免費”層是否會隨著時間的推移而過期,以及遷移到更昂貴層的價格是否意味著一開始就應該使用其他服務!
好訊息是,在開始時,有很多網站提供“免費”計算環境,這些環境旨在用於評估和測試。這些環境通常是資源受限/有限的環境,你確實需要意識到,它們可能會在一些入門期後過期,或者有其他限制。然而,它們非常適合在託管環境中測試低流量網站,並且可以輕鬆遷移到付費獲取更多資源,當你的網站變得更繁忙時。此類別的熱門選擇包括 Vultr Cloud Compute、Python Anywhere、Amazon Web Services、Microsoft Azure 等等。
大多數供應商還提供“基本”層,旨在用於小型生產網站,並且提供更實用的計算能力和更少的限制。Railway、Heroku 和 Digital Ocean 是流行的託管提供商的示例,它們提供相對便宜的基本計算層(每月 5 到 10 美元)。
注意:請記住,價格不是唯一的選擇標準。如果你的網站成功,可擴充套件性可能是最重要的考慮因素。
準備網站釋出
使用django-admin 和manage.py 工具建立的 Django 骨架網站 被配置為簡化開發。許多 Django 專案設定(在settings.py 中指定)應該在生產環境中有所不同,這可能是出於安全或效能方面的考慮。
注意:通常會為生產環境使用單獨的settings.py 檔案,或者有條件地從單獨的檔案或環境變數匯入敏感設定。然後應保護此檔案,即使其餘原始碼在公共儲存庫中可用。
你必須檢查的關鍵設定是
DEBUG。這應該在生產環境中設定為False(DEBUG = False)。這會阻止敏感/機密的除錯跟蹤和變數資訊顯示。SECRET_KEY。這是一個用於 CSRF 保護等的大型隨機值。重要的是,在生產環境中使用的金鑰不在原始碼控制中,也不在生產伺服器之外訪問。
Django 文件建議最好從環境變數載入秘密資訊,或者從僅伺服器檔案讀取。讓我們更改LocalLibrary 應用程式,以便如果定義了環境變數,我們從環境變數中讀取我們的SECRET_KEY 和DEBUG 變數,回退到在根目錄中定義的.env 檔案中的值,最後使用配置檔案中的預設值。這非常靈活,因為它允許任何由託管伺服器支援的配置。
為了從檔案讀取環境值,我們將使用 python-dotenv。這是一個用於從檔案讀取鍵值對並將其用作環境變數的庫,但前提是相應的環境變數沒有定義。
將庫安裝到你的虛擬環境中,如所示(並更新你的requirements.txt 檔案)
pip3 install python-dotenv
然後開啟/locallibrary/settings.py,在定義BASE_DIR 之後插入以下程式碼,但在安全警告之前:# SECURITY WARNING: keep the secret key used in production secret!
# Support env variables from .env file if defined
import os
from dotenv import load_dotenv
env_path = load_dotenv(os.path.join(BASE_DIR, '.env'))
load_dotenv(env_path)
這將從 Web 應用程式的根目錄載入.env 檔案。在檔案中定義為KEY=VALUE 的變數在os.environ.get('<KEY>'', '<DEFAULT VALUE>') 中使用該鍵時匯入,如果已定義。
注意:新增到.env 的任何值都可能是秘密!你不能將其儲存到 GitHub,並且應該將.env 新增到你的.gitignore 檔案中,以便不會意外新增它。
接下來,停用原始的SECRET_KEY 配置,並新增如下所示的新行。在開發過程中,不會為金鑰指定任何環境變數,因此將使用預設值(在這裡使用什麼金鑰並不重要,或者金鑰是否“洩漏”,因為你不會在生產環境中使用它)。
# SECURITY WARNING: keep the secret key used in production secret!
# SECRET_KEY = 'django-insecure-&psk#na5l=p3q8_a+-$4w1f^lt3lx1c@d*p4x$ymm_rn7pwb87'
import os
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'django-insecure-&psk#na5l=p3q8_a+-$4w1f^lt3lx1c@d*p4x$ymm_rn7pwb87')
然後註釋掉現有的DEBUG 設定,並新增如下所示的新行。
# SECURITY WARNING: don't run with debug turned on in production!
# DEBUG = True
DEBUG = os.environ.get('DJANGO_DEBUG', '') != 'False'
DEBUG 的值為True 為預設值,但只有在DJANGO_DEBUG 環境變數的值設定為False 或DJANGO_DEBUG=False 在.env 檔案中設定時,它才會為False。請注意,環境變數是字串,而不是 Python 型別。因此,我們需要比較字串。將DEBUG 變數設定為False 的唯一方法是實際將其設定為字串False。
您可以透過在 Linux 上執行以下命令將環境變數設定為“False”。
export DJANGO_DEBUG=False
您可能想要更改的設定的完整清單在 部署清單(Django 文件)中提供。您也可以使用以下終端命令列出其中一些
python3 manage.py check --deploy
Gunicorn
資料庫配置
SQLite 是您一直在用於開發的預設 Django 資料庫,對於小型到中型網站來說是一個合理的選擇。不幸的是,它無法在某些流行的託管服務(例如 Heroku)上使用,因為它們不在應用程式環境中提供持久資料儲存(SQLite 的一項要求)。雖然這可能不會影響我們示例部署,但我們將向您展示另一種方法,該方法適用於 Railway、Heroku 和其他一些服務。
這種方法是使用一個在網際網路上的某個位置的自己的程序中執行的資料庫,並使用作為環境變數傳遞的地址由 Django 庫應用程式訪問。在這種情況下,我們將使用一個也託管在 Railway 上的 Postgres 資料庫,但您可以使用任何您喜歡的資料庫託管服務。
資料庫連線資訊將使用名為 DATABASE_URL 的環境變數提供給 Django。與其將此資訊硬編碼到 Django 中,我們將使用 dj-database-url 包來解析 DATABASE_URL 環境變數並自動將其轉換為 Django 期望的配置格式。除了安裝 *dj-database-url* 包之外,我們還需要安裝 psycopg2,因為 Django 需要它與 Postgres 資料庫進行互動。
dj-database-url
*dj-database-url* 用於從環境變數中提取 Django 資料庫配置。
在本地安裝它,以便它成為我們在部署伺服器上設定的 需求 的一部分。
pip3 install dj-database-url
settings.py
開啟 **locallibrary/settings.py** 並將以下配置複製到檔案底部。
# Update database configuration from $DATABASE_URL environment variable (if defined)
import dj_database_url
if 'DATABASE_URL' in os.environ:
DATABASES['default'] = dj_database_url.config(
conn_max_age=500,
conn_health_checks=True,
)
如果設定了環境變數,Django 現在將使用 DATABASE_URL 中的資料庫配置;否則,它使用預設的 SQLite 資料庫。值 conn_max_age=500 使連線持久化,這比在每個請求週期重新建立連線效率高得多(這是可選的,如果需要可以刪除)。
psycopg2
Django 需要 *psycopg2* 來使用 Postgres 資料庫。在本地安裝它,以便它成為我們在 Railway 上設定的遠端伺服器的 需求 的一部分。
pip3 install psycopg2-binary
請注意,Django 預設情況下會在開發期間使用 SQLite 資料庫,除非設定了 DATABASE_URL。您可以完全切換到 Postgres 並使用同一個託管資料庫進行開發和生產,方法是在您的開發環境中設定同一個環境變數(Railway 使得輕鬆使用相同的環境進行生產和開發)。或者,您也可以在本地計算機上安裝和使用 自託管的 Postgres 資料庫。
在生產環境中提供靜態檔案
在開發過程中,我們使用 Django 和 Django 開發 Web 伺服器來為我們的動態 HTML 和靜態檔案(CSS、JavaScript 等)提供服務。對於靜態檔案來說,這是低效的,因為請求必須透過 Django,即使 Django 沒有對它們進行任何操作。雖然這在開發過程中無關緊要,但如果我們在生產環境中使用相同的方法,它會對效能產生重大影響。
在生產環境中,我們通常將靜態檔案與 Django Web 應用程式分開,從而更容易直接從 Web 伺服器或內容交付網路 (CDN) 提供服務。
重要的設定變數是
STATIC_URL:這是提供靜態檔案的基 URL 位置,例如在 CDN 上。STATIC_ROOT:這是 Django 的 *collectstatic* 工具將收集我們模板中引用的所有靜態檔案的目錄的絕對路徑。收集後,這些檔案可以作為一個組上傳到要託管檔案的任何位置。STATICFILES_DIRS:這列出了 Django 的 *collectstatic* 工具應該搜尋靜態檔案的其他目錄。
Django 模板引用相對於 static 標籤的靜態檔案位置(您可以在 Django 教程第 5 部分:建立我們的主頁 中定義的基模板中看到這一點),它反過來對映到 STATIC_URL 設定。因此,靜態檔案可以上傳到任何主機,您可以更新您的應用程式以使用此設定找到它們。
*collectstatic* 工具用於將靜態檔案收集到 STATIC_ROOT 專案設定中定義的資料夾中。它使用以下命令呼叫
python3 manage.py collectstatic
對於本教程,*collectstatic* 可以在應用程式上傳之前執行,將應用程式中的所有靜態檔案複製到 STATIC_ROOT 中指定的位置。Whitenoise 然後從 STATIC_ROOT 中定義的位置(預設情況下)找到檔案,並在 STATIC_URL 定義的基 URL 上提供服務。
settings.py
開啟 **locallibrary/settings.py** 並將以下配置複製到檔案底部。BASE_DIR 應該已經在您的檔案中定義(STATIC_URL 可能在建立檔案時已經定義在檔案中。雖然這不會造成任何傷害,但您也可以刪除重複的先前引用)。
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
# The absolute path to the directory where collectstatic will collect static files for deployment.
STATIC_ROOT = BASE_DIR / 'staticfiles'
# The URL to use when referring to static files (where they will be served from)
STATIC_URL = '/static/'
我們實際上將使用名為 WhiteNoise 的庫來執行檔案提供服務,我們將在下一節中安裝和配置它。
Whitenoise
在生產環境中提供靜態檔案有很多方法(我們在前幾節中看到了相關的 Django 設定)。WhiteNoise 專案為直接從生產環境中的 Gunicorn 提供靜態資產提供了最簡單的方法之一。
檢視 WhiteNoise 文件,瞭解它是如何工作的以及為什麼這種實現是提供這些檔案的相對有效方法。
設定 *WhiteNoise* 以與專案一起使用的步驟 在此處給出(並複製到下面)。
安裝 whitenoise
使用以下命令在本地安裝 whitenoise
pip3 install whitenoise
settings.py
要將 *WhiteNoise* 安裝到您的 Django 應用程式中,請開啟 **locallibrary/settings.py**,找到 MIDDLEWARE 設定並將 WhiteNoiseMiddleware 新增到列表的頂部附近,就在 SecurityMiddleware 下面。
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
可選地,您可以減少靜態檔案在提供服務時的檔案大小(這更有效率)。只需將以下內容新增到 **locallibrary/settings.py** 的底部。
# Static file serving.
# https://whitenoise.readthedocs.io/en/stable/django.html#add-compression-and-caching-support
STORAGES = {
# ...
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
}
您不需要執行任何其他操作來配置 *WhiteNoise*,因為它預設使用您的專案設定中的 STATIC_ROOT 和 STATIC_URL。
需求
您的 Web 應用程式的 Python 需求應該儲存在您的儲存庫根目錄中的 **requirements.txt** 檔案中。許多託管服務會自動安裝此檔案中的依賴項(在其他服務中,您必須自己執行此操作)。您可以使用命令列上的 *pip* 建立此檔案(在倉庫根目錄中執行以下命令)。
pip3 freeze > requirements.txt
在安裝了上面所有不同的依賴項後,您的 **requirements.txt** 檔案應該至少列出這些專案(儘管版本號可能不同)。請刪除下面未列出的任何其他依賴項,除非您已明確為此應用程式添加了它們。
Django==5.0.2 dj-database-url==2.1.0 gunicorn==21.2.0 psycopg2-binary==2.9.9 wheel==0.38.1 whitenoise==6.6.0 python-dotenv==1.0.1
更新您在 GitHub 中的應用程式倉庫
許多託管服務允許您從本地倉庫或雲端原始碼控制平臺匯入或同步專案。這可以使部署和迭代開發變得容易得多。
您應該已經在使用 GitHub 來儲存本地庫原始碼(這在 使用 Git 和 GitHub 進行原始碼管理 中作為設定您的開發環境的一部分而設定)。
現在是備份您的“原始”專案的好時機——雖然我們在以下幾節中進行的一些更改可能對在任何託管服務(或開發)中部署有用,但其他更改可能沒有用。假設您已經備份了迄今為止對 GitHub 上的 main 分支所做的所有更改,您可以建立一個新分支來備份您的更改,如下所示
# Fetch the latest main branch
git checkout main
git pull origin main
# Create branch vanilla_deployment from the current branch (main)
git checkout -b vanilla_deployment
# Push the new branch to GitHub
git push origin vanilla_deployment
# Switch back to main
git checkout main
# Make any further changes in a new branch
git checkout -b my_changes_for_deployment # Create a new branch
示例:在 PythonAnywhere 上託管
本節提供了在 PythonAnywhere 上託管 *LocalLibrary* 的實際演示。
為什麼選擇 PythonAnywhere?
我們選擇使用 PythonAnywhere 是因為以下幾個原因。
- PythonAnywhere 擁有 免費的初學者計劃,它是 *真正* 免費的,儘管有一些限制。它對所有開發人員來說都是負擔得起的,這對 MDN 來說非常重要!
注意:本教程已託管在 Heroku、Railway,現在是 PythonAnywhere 上,在之前免費計劃停止服務後進行了遷移。我們選擇 PythonAnywhere,因為我們認為該計劃很可能仍然免費。我們也保留了 Railway 示例,它不是免費的,用於比較,因為它允許我們更輕鬆地演示諸如與在不同服務上執行的 Postgres 資料庫整合之類的功能。
- PythonAnywhere 負責基礎設施,因此您無需擔心。不必擔心伺服器、負載均衡器、反向代理等等,使入門變得容易得多。
- 您在使用 PythonAnywhere 時學習的技能和概念是可轉移的。
- 服務和計劃限制不會特別影響我們使用 PythonAnywhere 進行教程。例如
- 初學者計劃允許在
<your-username>.pythonanywhere.com上有一個 Web 應用程式,應用程式的出站網際網路訪問受限,CPU/頻寬低,沒有 IPython/Jupyter Notebook 支援,沒有免費的 Postgres 資料庫。但我們的基本網站有足夠的空間執行! - 不支援自定義域(截至撰寫本文時)。
- 環境在不使用時會關閉,因此可能難以重新啟動。您可以無限期地執行它,但您需要每三個月訪問一次網站並續訂 Web 應用程式。
- 有一個單獨的 MySQL 資料庫的免費支援,但沒有 Postgres 支援。在本演示中,我們將只使用 Django 在託管的 Ubuntu 環境中建立的預設 SQLite 資料庫(有足夠的空間來演示庫功能)。
- 初學者計劃允許在
PythonAnywhere 適用於託管本演示,如果需要可以擴充套件到更大的專案。您應該花時間確定它是否 適合您自己的網站。
PythonAnywhere 如何運作?
PythonAnywhere 提供了一個完全基於 Web 的介面,用於上傳、編輯和以其他方式處理您的應用程式。
透過介面,您可以啟動一個 bash 控制檯到 Ubuntu Linux 環境,您可以在其中建立您的應用程式。在本演示中,我們將使用控制檯來克隆我們的本地庫 GitHub 倉庫,並建立一個可以在其中執行 Web 應用程式的 Python 環境。
免費計劃不提供單獨的 Postgres 支援。雖然我們可以使用其他一些託管服務來託管我們的資料庫,但我們將只使用 Django 在託管的 Ubuntu 環境中建立的預設 SQLite 資料庫(有足夠的空間來演示庫功能)。
應用程式執行後,可以透過 bash 控制檯設定環境變數來配置應用程式以進行生產。
這是你入門所需的所有概述。
獲取 PythonAnywhere 帳戶
要開始使用 PythonAnywhere,您首先需要建立一個帳戶。
- 訪問 PythonAnywhere 計劃和定價 頁面,然後選擇建立初學者帳戶按鈕。
- 使用您的使用者名稱、電子郵件和密碼建立一個帳戶,確認條款和條件,然後選擇註冊。
- 然後您將登入並重定向到 PythonAnywhere 儀表板:
https://www.pythonanywhere.com/user/<your_user_name>/。
從 GitHub 安裝庫
接下來我們將開啟一個 Bash 提示符,設定一個虛擬環境,並從 GitHub 獲取本地庫原始碼。我們還將配置預設資料庫並收集靜態檔案,以便 PythonAnywhere 可以提供服務。
- 首先透過選擇頂部的應用程式欄中的控制檯開啟控制檯管理螢幕。
- 然後選擇Bash連結以建立並啟動一個新控制檯:
請注意,您建立的任何控制檯都會儲存以供您以後重新使用,以及其所有歷史記錄。上面的綠色箭頭顯示此帳戶有一個我們可以開啟的控制檯。 - 在控制檯中,輸入以下命令以建立一個名為“env_local_library”的 Python 3.10 虛擬環境,用於安裝本地庫依賴項。這與設定 Django 開發環境中介紹的過程完全相同。我們可以將環境命名為任何名稱,並且可以使用以下命令停用和重新啟用它。bash
mkvirtualenv --python=python3.10 env_local_librarybashdeactivate workon env_local_library - 接下來從 GitHub 獲取庫原始碼。PythonAnywhere 預計您將應用程式安裝到以您的網站 URL 命名的資料夾中。輸入以下命令將您的庫原始碼克隆到一個正確命名的資料夾中(您需要將使用者名稱值替換為自己的名稱)
注意:因為我們使用的是免費帳戶,所以您只能將帳戶命名為
<your_pythonaware_username>.pythonanywhere.com(例如,如果您的使用者名稱是“Odtsetseg”,則必須將本地庫原始碼放入一個名為odtsetseg.pythonanywhere.com的資料夾中)。bashgit clone https://github.com/<github_username>/django-locallibrary-tutorial.git <pythonaware_username>.pythonanywhere.com # Navigate into the new folder cd <pythonaware_username>.pythonanywhere.com - 使用
requirements.txt檔案安裝庫依賴項bashpip3 install -r requirements.txt - 在託管計算機上建立和配置一個 SQLite 資料庫(就像我們在開發過程中做的那樣)。bash
python manage.py migrate注意:對於 Railway 示例,我們將配置一個 Postgres 資料庫,並透過設定
DATABASE_URL環境變數連線到它。重要的是,在配置要使用哪個資料庫之後,要呼叫migrate。 - 將所有靜態檔案收集到一個位置,以便可以在生產環境中提供服務bash
python manage.py collectstatic --no-input - 建立一個超級使用者以訪問網站(如Django 管理員網站部分所述)請注意詳細資訊,因為您需要它們來測試您的網站。bash
python manage.py createsuperuser
設定 Web 應用程式
在獲取本地庫原始碼並在虛擬環境中安裝依賴項之後,我們需要告訴 PythonAnywhere 如何找到它們並將它們用作 Web 應用程式。
- 導航到網站的Web部分,然後選擇新增新 Web 應用程式連結:
然後將開啟建立新 Web 應用程式嚮導,指導您完成配置 Web 應用程式的主要屬性。 - 選擇下一步跳過 Web 應用程式域名配置。免費帳戶將根據您的使用者名稱建立域名:
<user_name>.pythonanywhere.com。
- 在選擇一個 Python Web 框架螢幕中,選擇手動配置。
手動配置使我們能夠完全控制環境的配置方式。現在這並不重要,但如果我們要託管多個站點,可能使用不同版本的 Python 和/或 Django,則會很重要。 - 在選擇一個 Python 版本螢幕中,選擇3.10
更一般地說,您應該選擇您正在使用的 Django 版本允許的最新版本的 Python。 - 在手動配置螢幕中,選擇下一步(該螢幕只是解釋了一些配置選項)
Web 應用程式已建立,並在Web部分中顯示,如所示。該螢幕有一個重新載入按鈕,您可以在對配置進行任何進一步更改後使用它來重新載入 Web 應用程式。如螢幕上所述,您需要單擊執行到今天起 3 個月按鈕以使網站保持活動狀態另外三個月(以及以後)。
- 向下滾動到Web選項卡的“程式碼”部分,然後選擇指向 WSGI 配置檔案的連結。這將有一個以
/var/www/<user_name>_pythonanywhere_com_wsgi.py形式命名的名稱。
將檔案中的內容替換為以下文字(首先使用您的使用者名稱更新“hamishwillee”),然後選擇儲存按鈕。請注意,WSGI 檔案的作用是幫助 Gunicorn 伺服器找到本地庫應用程式。PythonAnywhere 預計此檔案位於此位置,這就是為什麼專案中已經存在的 WSGI 檔案不能使用的原因。pyimport os import sys path = '/home/hamishwillee/hamishwillee.pythonanywhere.com' if path not in sys.path: sys.path.append(path) os.environ['DJANGO_SETTINGS_MODULE'] = 'locallibrary.settings' from django.core.wsgi import get_wsgi_application application = get_wsgi_application() - 向下滾動到Web選項卡的“Virtualenv”部分。選擇連結輸入虛擬環境的路徑(如果需要),然後輸入上一節中建立的虛擬環境的路徑。如果您將其命名為“env_local_library”如建議,則路徑將為:
/home/<user_name>/.virtualenvs/env_local_library
- 向下滾動到Web選項卡的“靜態檔案”部分。
選擇輸入 URL連結,然後輸入\static_files\。這是應用程式設定中的STATIC_URL,它反映了在上一節中執行collectstatic時複製檔案的路徑。 - 在Web選項卡的頂部附近,選擇重新載入按鈕以重新啟動網站。然後選擇網站 URL 連結以啟動即時網站。
設定 ALLOWED_HOSTS 和 CSRF_TRUSTED_ORIGINS
開啟網站後,此時您將看到下面顯示的錯誤除錯螢幕。這是一個 Django 安全錯誤,它被引發是因為我們的原始碼沒有在“允許的宿主”上執行。
注意:此類除錯資訊在您進行設定時非常有用,但在已部署的網站中存在安全風險。在下一節中,我們將向您展示如何使用環境變數在即時網站上停用此級別的日誌記錄。
在您的 GitHub 專案中開啟/locallibrary/settings.py,並將ALLOWED_HOSTS設定更改為包含您的 PythonAnywhere 網站 URL
## For example, for a site URL at 'hamishwillee.pythonanywhere.com'
## (replace the string below with your own site URL):
ALLOWED_HOSTS = ['hamishwillee.pythonanywhere.com', '127.0.0.1']
# During development, you can instead set just the base URL
# (you might decide to change the site a few times).
# ALLOWED_HOSTS = ['.pythonanywhere.com','127.0.0.1']
由於應用程式使用 CSRF 保護,因此您還需要設定CSRF_TRUSTED_ORIGINS鍵。開啟/locallibrary/settings.py並新增類似於下面的一行
## For example, for a site URL is at 'web-production-3640.up.railway.app'
## (replace the string below with your own site URL):
CSRF_TRUSTED_ORIGINS = ['https://hamishwillee.pythonanywhere.com']
# During development/for this tutorial you can instead set just the base URL
# CSRF_TRUSTED_ORIGINS = ['https://*.pythonanywhere.com']
儲存這些設定並將它們提交到您的 GitHub 儲存庫。
然後您需要更新 PythonAnywhere 上的專案版本。假設您正在使用您在資料夾<user_name>.pythonanywhere.com中的 Bash 提示符,並且您已將更改推送到主分支,那麼您可以使用以下命令在 Bash 提示符中匯入它們
git pull origin main
使用Web選項卡上的重新啟動按鈕重新啟動應用程式。如果您重新整理託管的網站,它現在應該開啟並顯示網站的主頁。
您應該能夠使用上面建立的超級使用者帳戶登入,並建立作者、流派、書籍等,就像您在本地計算機上做的那樣。
在 PythonAnywhere 上使用環境變數
在準備釋出您的網站部分中,我們修改了應用程式,使其可以使用環境變數或生產環境中.env檔案中的變數進行配置。
具體來說,我們設定了庫,以便您可以設定
DJANGO_DEBUG=False以減少在發生錯誤時顯示給使用者的除錯跟蹤。DJANGO_SECRET_KEY在生產環境中設定為某個秘密值。DATABASE_URL如果您的應用程式使用託管資料庫(在本示例中我們沒有使用)。
設定環境變數的方式取決於託管服務。對於 PythonAnywhere,您需要從環境檔案中讀取它們。我們已經為此做好了準備,因此我們所需要做的就是建立該檔案。
步驟如下
- 開啟一個 PythonAware Bash 提示符。
- 導航到您的應用程式目錄(用您自己的帳戶替換
<user-name>)bashcd ~/<user-name>.pythonanywhere.com - 透過將環境變數作為鍵值對寫入
.env檔案來設定它們。例如,要在 Bash 控制檯中將DJANGO_DEBUG設定為False,請輸入以下命令bashecho "DJANGO_DEBUG=False" >> .env - 重新啟動應用程式。
您可以嘗試開啟一個不存在的記錄(例如,建立一個流派,然後在 URL 欄中增加數字以開啟尚未建立的記錄)來測試操作是否成功。如果環境變數已載入,您將收到“未找到”訊息而不是詳細的除錯跟蹤。
示例:在 Railway 上託管
本節提供了關於如何在Railway上安裝LocalLibrary的實際演示。
為什麼選擇 Railway?
警告:Railway 不再擁有完全免費的入門層。我們保留了這些說明,因為 Railway 有一些很棒的功能,對於某些使用者來說將是一個更好的選擇。
Railway 由於以下幾個原因成為一個有吸引力的託管選項
- Railway 處理了大多數基礎設施,因此您不必擔心。不必擔心伺服器、負載均衡器、反向代理等,這使得入門變得容易得多。
- Railway 專注於開發和部署的開發人員體驗,這導致比許多其他替代方案更快、更平緩的學習曲線。
- 使用 Railway 時您將學習的技能和概念是可以轉移的。雖然 Railway 有一些很棒的新功能,但其他流行的託管服務使用了許多相同的理念和方法。
- Railway 文件清晰完整。
- 該服務似乎非常可靠,如果您最終喜歡它,定價是可預測的,而且擴充套件您的應用程式非常容易。
您應該花時間確定 Railway 是否適合您的網站。
Railway 如何工作?
每個 Web 應用程式都在其自己的隔離且獨立的虛擬化容器中執行。為了執行您的應用程式,Railway 需要能夠設定適當的環境和依賴項,並瞭解其啟動方式。對於 Django 應用程式,我們在幾個文字檔案中提供此資訊。
- runtime.txt:指定要使用的程式語言和版本。
- requirements.txt:列出您的網站所需的 Python 依賴項,包括 Django。
-
Procfile:要執行以啟動 Web 應用程式的程序列表。對於 Django,這通常是 Gunicorn Web 應用程式伺服器(使用
.wsgi指令碼)。 - wsgi.py:WSGI 配置,用於在 Railway 環境中呼叫我們的 Django 應用程式。
應用程式執行後,它可以使用 環境變數 中提供的資訊進行配置。例如,使用資料庫的應用程式可以使用變數 DATABASE_URL 獲取地址。資料庫服務本身可能由 Railway 或其他提供商託管。
開發人員透過 Railway 網站以及一個特殊的 命令列介面 (CLI) 工具與 Railway 互動。CLI 允許您將本地 GitHub 儲存庫與 Railway 專案關聯,將本地分支中的儲存庫上傳到即時站點,檢查執行程序的日誌,設定和獲取配置變數等等。最有用的一項功能是,您可以使用 CLI 在與即時專案相同的環境變數下執行本地專案。
為了使我們的應用程式在 Railway 上執行,我們需要將 Django Web 應用程式放入一個 git 儲存庫中,新增上面的檔案,與資料庫附加元件整合,並進行更改以正確處理靜態檔案。完成所有這些操作後,我們可以設定一個 Railway 帳戶,獲取 Railway 客戶端並安裝我們的網站。
這就是您入門所需的所有概述。
更新 Railway 的應用程式
本節說明您需要對我們的 LocalLibrary 應用程式進行的更改,以使其在 Railway 上執行。我們實際上只需要建立一個 Procfile 和 runtime.txt 檔案,因為其他幾乎所有內容都已經存在。
請注意,這些更改不會阻止您使用我們已經學習過的本地測試和工作流程。
Procfile
Procfile 是 Web 應用程式的“入口點”。它列出了 Railway 執行以啟動您的網站的命令。
在 GitHub 儲存庫的根目錄中建立名為 Procfile 的檔案(沒有副檔名),並將以下文字複製貼上到其中
web: python manage.py migrate && python manage.py collectstatic --no-input && gunicorn locallibrary.wsgi
web: 字首告訴 Railway 這是一個 Web 程序,可以傳送 HTTP 流量。然後,我們呼叫 Django 遷移命令 python manage.py migrate 來設定資料庫表。接下來,我們呼叫 Django 命令 python manage.py collectstatic 將靜態檔案收集到 STATIC_ROOT 專案設定中定義的資料夾中(參見下面的 在生產環境中提供靜態檔案 部分)。最後,我們啟動 gunicorn 程序(一個流行的 Web 應用程式伺服器),並將配置資訊傳遞給模組 locallibrary.wsgi(使用我們的應用程式骨架建立:/locallibrary/wsgi.py)。
您會注意到我們已經設定了專案以包含 gunicorn 並支援提供靜態檔案!
您還可以使用 Procfile 啟動工作程序或在釋出部署之前執行其他非互動式任務。
執行時
runtime.txt 檔案(如果已定義)會告訴 Railway 使用哪個版本的 Python。在儲存庫的根目錄中建立該檔案,並新增以下文字
python-3.10.2
注意:託管提供商並不一定支援每個 Python 執行時次要版本。它們通常會使用與您指定的版本最接近的支援版本。
重新測試並儲存更改到 GitHub
在繼續操作之前,請先在本地再次測試網站,並確保上述任何更改都沒有破壞網站。照常執行開發 Web 伺服器,然後檢查網站在您的瀏覽器中按預期執行。
python3 manage.py runserver
接下來,將更改 push 到 GitHub。在終端(導航到本地儲存庫後),輸入以下命令
git checkout -b railway_changes
git add -A
git commit -m "Added files and changes required for deployment"
git push origin railway_changes
然後在 GitHub 上建立併合並 PR。
現在我們應該可以開始在 Railway 上部署 LocalLibrary 了。
獲取 Railway 帳戶
要開始使用 Railway,您首先需要建立一個帳戶
- 訪問 railway.app,然後單擊頂部工具欄中的 登入 連結。
- 在彈出視窗中選擇 GitHub,使用您的 GitHub 憑據登入
- 然後,您可能需要訪問您的電子郵件並驗證您的帳戶。
- 然後您將登入到 Railway.app 儀表板:https://railway.app/dashboard。
從 GitHub 在 Railway 上部署
接下來,我們將設定 Railway 以從 GitHub 部署我們的庫。首先從網站頂部選單中選擇 儀表板 選項,然後選擇 新建專案 按鈕
Railway 將顯示新專案的選項列表,包括從首先在您的 GitHub 帳戶中建立的模板部署專案,以及許多資料庫。選擇 從 GitHub 儲存庫部署。
將顯示您在設定過程中與 Railway 共享的 GitHub 儲存庫中的所有專案。為本地庫選擇您的 GitHub 儲存庫:<user-name>/django-locallibrary-tutorial。
透過選擇 立即部署 確認您的部署。
然後,Railway 將載入並部署您的專案,並在部署選項卡中顯示進度。當部署成功完成時,您將看到類似於下面的螢幕。
您可以單擊站點 URL(上面突出顯示)在瀏覽器中開啟站點(它仍然無法正常執行,因為設定尚未完成)。
設定 ALLOWED_HOSTS 和 CSRF_TRUSTED_ORIGINS
開啟網站後,此時您將看到下面顯示的錯誤除錯螢幕。這是一個 Django 安全錯誤,它被引發是因為我們的原始碼沒有在“允許的宿主”上執行。
注意:這種除錯資訊在您進行設定時非常有用,但在部署的站點中存在安全風險。我們將向您展示如何在站點啟動並執行後停用它。
在您的 GitHub 專案中開啟 /locallibrary/settings.py,並將 ALLOWED_HOSTS 設定更改為包括您的 Railway 站點 URL
## For example, for a site URL at 'web-production-3640.up.railway.app'
## (replace the string below with your own site URL):
ALLOWED_HOSTS = ['web-production-3640.up.railway.app', '127.0.0.1']
# During development, you can instead set just the base URL
# (you might decide to change the site a few times).
# ALLOWED_HOSTS = ['.railway.com','127.0.0.1']
由於應用程式使用 CSRF 保護,因此您還需要設定CSRF_TRUSTED_ORIGINS鍵。開啟/locallibrary/settings.py並新增類似於下面的一行
## For example, for a site URL is at 'web-production-3640.up.railway.app'
## (replace the string below with your own site URL):
CSRF_TRUSTED_ORIGINS = ['https://web-production-3640.up.railway.app']
# During development/for this tutorial you can instead set just the base URL
# CSRF_TRUSTED_ORIGINS = ['https://*.railway.app']
然後儲存您的設定並將它們提交到您的 GitHub 儲存庫(Railway 將自動更新並重新部署您的應用程式)。
預配並連線 PostgreSQL 資料庫
接下來,我們需要建立一個 PostgreSQL 資料庫並將其連線到我們剛剛部署的 Django 應用程式。(如果您現在開啟站點,您將收到一個新的錯誤,因為無法訪問資料庫)。我們將作為應用程式專案的一部分建立資料庫,儘管您可以在單獨的專案中建立資料庫。
在 Railway 上,從網站頂部選單中選擇 儀表板 選項,然後選擇您的應用程式專案。在此階段,它只包含您應用程式的單個服務(可以選擇它來設定服務的變數和其他詳細資訊)。設定按鈕可用於更改專案範圍的設定。選擇 新建 按鈕,用於將服務新增到專案中。
當系統提示您有關要新增的服務型別時,請選擇 資料庫
然後選擇 新增 PostgreSQL 開始新增資料庫
然後,Railway 將在同一個專案中預配包含一個空資料庫的服務。完成後,您將在專案檢視中看到應用程式和資料庫服務。
選擇 Web 服務,然後選擇 變數 選項卡。選擇 新建變數,然後在 變數名稱 框中,選擇 新增引用。向下滾動並選擇 DATABASE_URL(這是我們設定 locallibrary 以讀取為環境變數的變數的名稱)。
然後選擇 新增 新增變數引用,最後選擇 部署(這將出現在一個彈出視窗中)。請注意,您也可以開啟 PostgreSQL 資料庫,然後開啟其變數選項卡,並將變數複製過來。
如果您現在開啟專案,它應該與本地顯示的完全相同。但是請注意,目前無法使用資料填充庫,因為我們還沒有建立超級使用者帳戶。我們將使用本地計算機上的 CLI 工具來執行此操作。
安裝客戶端
按照 此處說明 下載並安裝適用於您本地作業系統的 Railway 客戶端。
安裝客戶端後,您將能夠執行命令。一些更重要的操作包括將計算機的當前目錄部署到關聯的 Railway 專案(無需上傳到 GitHub),以及使用與生產伺服器上相同的設定在本地執行 Django 專案。我們在下一節中將介紹這些操作。
您可以透過在終端中輸入以下內容來獲取所有可能命令的列表。
railway help
注意:在以下部分中,我們使用 railway login 和 railway link 將當前專案連結到一個目錄。如果您被系統登出,則需要再次呼叫這兩個命令才能重新連結專案。
配置超級使用者
為了建立超級使用者,我們需要對生產資料庫呼叫 Django createsuperuser 命令(這與我們在 Django 教程第 4 部分:Django 管理員站點 > 建立超級使用者 中本地執行的操作相同)。Railway 不提供對伺服器的直接終端訪問,我們無法將此命令新增到 Procfile 中,因為它具有互動性。
我們可以做的是,當 Django 專案連線到 生產 資料庫時,在本地呼叫此命令。Railway 客戶端透過提供一種機制來在使用與生產伺服器相同的環境變數(包括資料庫連線字串)的情況下在本地執行命令,使這一操作變得容易。
首先在 locallibrary 專案的 git 克隆中開啟一個終端或命令提示符。然後使用 login 或 login --browserless 命令登入到您的瀏覽器帳戶(按照客戶端或網站的任何後續提示和說明完成登入)
railway login
登入後,使用以下命令將您當前的 locallibrary 目錄連結到關聯的 Railway 專案。請注意,您需要在系統提示時選擇/輸入一個特定的專案
railway link
現在本地目錄和專案已 連結,您可以使用生產環境中的設定執行本地 Django 專案。首先確保您的正常 Django 開發環境 已準備就緒。然後呼叫以下命令,根據需要輸入名稱、電子郵件和密碼
railway run python manage.py createsuperuser
現在,您應該能夠開啟您的網站管理員區域(https://[your-url].railway.app/admin/)並填充資料庫,就像在 Django 教程第 4 部分:Django 管理員站點 中所示。
設定配置變數
最後一步是使站點安全。具體來說,我們需要停用除錯日誌記錄並設定一個秘密 CSRF 金鑰。在 準備網站釋出 中完成了從環境變數讀取所需值的步驟(參見 DJANGO_DEBUG 和 DJANGO_SECRET_KEY)。
開啟專案的詳細資訊螢幕,然後選擇 變數 選項卡。這應該已經包含 DATABASE_URL,如下所示。
生成加密金鑰的方法有很多。一個簡單的方法是在您的開發計算機上執行以下 Python 命令
python -c "import secrets; print(secrets.token_urlsafe())"
選擇**新建變數**按鈕,並輸入金鑰 `DJANGO_SECRET_KEY` 和您的金鑰值(然後選擇**新增**)。然後輸入金鑰 `DJANGO_DEBUG` 和值 `False`。最終的變數集應如下所示
除錯
總結
在本教程中,我們將介紹如何在生產環境中設定 Django 應用程式,以及關於使用 Django 的一系列教程。我們希望您發現它們有用。您可以檢視 GitHub 上的完整原始碼。
下一步是閱讀我們最後幾篇文章,然後完成評估任務。
另請參閱
- 部署 Django(Django 文件)
- 部署清單(Django 文件)
- 部署靜態檔案(Django 文件)
- 如何使用 WSGI 部署(Django 文件)
- 如何使用 Apache 和 mod_wsgi 與 Django 協同工作(Django 文件)
- 如何使用 Gunicorn 與 Django 協同工作(Django 文件)
- Railway 文件
- Digital Ocean
- Heroku 文件(類似的設定概念)
- 為 Heroku 配置 Django 應用程式(Heroku 文件)
- 在 Heroku 上使用 Django 入門(Heroku 文件)
- Django 和靜態資源(Heroku 文件)
- Django 中的併發和資料庫連線(Heroku 文件)
- Heroku 工作原理(Heroku 文件)
- Dynos 和 Dyno 管理器(Heroku 文件)
- 配置和配置變數(Heroku 文件)
- 限制(Heroku 文件)
- 使用 Gunicorn 部署 Python 應用程式(Heroku 文件)
- 在 Heroku 上部署 Python 和 Django 應用程式(Heroku 文件)