Django 教程第 11 部分:將 Django 部署到生產環境
你已經使用 Django 建立並測試了示例網站,現在是時候將其安裝到 Web 伺服器上,以便任何人都可以透過公共網際網路訪問它。本頁介紹瞭如何託管 Django 專案以及你需要為生產部署做哪些準備。
| 預備知識 | 完成之前所有的教程主題,包括Django 教程第 10 部分:測試 Django Web 應用程式。 |
|---|---|
| 目標 | 學習可以在何處以及如何將 Django 應用部署到生產環境。 |
概述
當你的網站完成(或“足夠完成”以開始公開測試)後,你需要將其託管在一個比你個人開發計算機更公開、更易於訪問的地方。
到目前為止,你一直在開發環境中工作,使用 Django 開發 Web 伺服器將你的網站共享到本地瀏覽器/網路,並使用(不安全的)開發設定執行你的網站,這些設定會暴露除錯和其他私人資訊。在你可以在外部託管網站之前,你首先需要:
- 對你的專案設定進行一些更改。
- 選擇一個用於託管 Django 應用的環境。
- 選擇一個用於託管任何靜態檔案的環境。
- 為你的網站設定一個生產級別的基礎設施。
本教程為你選擇託管站點提供了一些指導,簡要概述了為了讓你的 Django 應用準備好生產環境需要做些什麼,並提供了一個將 LocalLibrary 網站安裝到 Railway 雲託管服務上的工作示例。
什麼是生產環境?
生產環境是伺服器計算機提供的環境,你將在其中執行你的網站供外部消費。該環境包括:
- 網站執行的計算機硬體。
- 作業系統(例如 Linux、Windows)。
- 你的網站所基於的程式語言執行時和框架庫。
- 用於提供頁面和其他內容的 Web 伺服器(例如 Nginx、Apache)。
- 在你的 Django 網站和 Web 伺服器之間傳遞“動態”請求的應用伺服器。
- 你的網站所依賴的資料庫。
備註: 根據你的生產環境配置,你可能還會有一個反向代理、負載均衡器等。
伺服器計算機可以位於你的場所內,透過高速連結連線到網際網路,但更常見的是使用託管在“雲端”的計算機。這實際上意味著你的程式碼執行在你的託管公司資料中心裡的某個遠端計算機(或可能是“虛擬”計算機)上。遠端伺服器通常會以一定的價格提供一定水平的計算資源(CPU、RAM、儲存記憶體等)和網際網路連線。
這種可遠端訪問的計算/網路硬體被稱為基礎設施即服務 (IaaS)。許多 IaaS 供應商提供預裝特定作業系統的選項,你必須在其上安裝生產環境的其他元件。其他供應商則允許你選擇功能更齊全的環境,可能包括一個完整的 Django 和 Web 伺服器設定。
備註: 預構建的環境可以使你的網站設定非常容易,因為它們減少了配置,但可用的選項可能會限制你使用不熟悉的伺服器(或其他元件),並且可能基於較舊版本的作業系統。通常情況下,最好自己安裝元件,這樣你可以得到你想要的元件,當需要升級系統部分時,你也有個大致的瞭解!
其他託管提供商將 Django 作為平臺即服務 (PaaS) 產品的一部分來支援。在這種託管方式中,你不需要擔心大部分的生產環境(Web 伺服器、應用伺服器、負載均衡器),因為託管平臺會為你處理這些——以及為了擴充套件你的應用所需的大部分工作。這使得部署變得非常簡單,因為你只需要專注於你的 Web 應用程式,而不是所有其他的伺服器基礎設施。
一些開發者會選擇 IaaS 提供的更大靈活性而不是 PaaS,而另一些開發者則會欣賞 PaaS 減少的維護開銷和更容易的擴充套件性。當你剛開始時,在 PaaS 系統上設定你的網站要容易得多,因此我們將在本教程中這樣做。
備註: 如果你選擇一個對 Python/Django 友好的託管提供商,他們應該會提供關於如何使用不同配置的 Web 伺服器、應用伺服器、反向代理等來設定 Django 網站的說明(如果你選擇 PaaS,這將不相關)。例如,DigitalOcean Django 社群文件中有許多針對各種配置的逐步指南。
選擇託管服務提供商
有許多託管提供商已知積極支援或與 Django 良好協作,包括:Heroku、DigitalOcean、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 和 DigitalOcean 是擁有相對便宜的基礎計算層級(每月 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 檔案。當在 os.environ.get('<KEY>'', '<DEFAULT VALUE>') 中使用鍵時,如果檔案中定義了形如 KEY=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 或在 .env 檔案中設定了 DJANGO_DEBUG=False 時,它才會是 False。請注意,環境變數是字串而不是 Python 型別。因此,我們需要比較字串。將 DEBUG 變數設定為 False 的唯一方法是實際將其設定為字串 'False'。
你可以在 Linux 上透過發出以下命令將環境變數設定為“False”:
export DJANGO_DEBUG=False
你可能想要更改的設定的完整清單可以在部署清單(Django 文件)中找到。你也可以使用下面的終端命令列出其中的一些:
python3 manage.py check --deploy
Gunicorn
Gunicorn 是一個純 Python HTTP 伺服器,通常用於為 Django WSGI 應用程式提供服務。
雖然在開發期間我們不需要Gunicorn來為我們的 LocalLibrary 應用程式提供服務,但我們會在本地安裝它,以便在部署應用程式時它成為我們需求的一部分。
首先確保你處於設定開發環境時建立的 Python 虛擬環境中(使用 workon [name-of-virtual-environment] 命令)。然後在命令列中使用 pip 在本地安裝 Gunicorn:
pip3 install gunicorn
資料庫配置
SQLite 是你一直在開發中使用的預設 Django 資料庫,對於中小型網站來說是一個合理的選擇。不幸的是,它不能在一些流行的託管服務(如 Heroku)上使用,因為它們在應用程式環境中不提供持久資料儲存(這是 SQLite 的要求)。雖然這可能不會影響我們的示例部署,但我們將向你展示另一種在 Railway、Heroku 和其他一些服務上可行的方法。
方法是使用一個在網際網路上某個地方以其自身程序執行的資料庫,並透過作為環境變數傳遞的地址由 Django 庫應用程式訪問。在這種情況下,我們將使用一個也託管在 Railway 上的 Postgres 資料庫,但你可以使用任何你喜歡的資料庫託管服務。
資料庫連線資訊將透過名為 DATABASE_URL 的環境變數提供給 Django。我們將使用 dj-database-url 包來解析 DATABASE_URL 環境變數,並自動將其轉換為 Django 所需的配置格式,而不是在 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
請注意,除非設定了 DATABASE_URL,否則 Django 在開發期間將預設使用 SQLite 資料庫。你可以完全切換到 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 的介面,用於上傳、編輯和以其他方式處理你的應用程式。
透過這個介面,你可以啟動一個連線到 Ubuntu Linux 環境的 bash 控制檯,在其中建立你的應用程式。在這個演示中,我們將使用控制檯克隆我們的本地圖書館 GitHub 倉庫,並建立一個可以執行 Web 應用程式的 Python 環境。
免費計劃不提供獨立的 Postgres 支援。雖然我們可以使用其他託管服務來託管我們的資料庫,但我們將只使用 Django 在託管的 Ubuntu 環境中建立的預設 SQLite 資料庫(有足夠的空間來演示圖書館的功能)。
一旦應用程式執行起來,就可以透過 bash 控制檯設定環境變數來進行生產環境配置。
這就是開始所需的所有概述。
獲取一個 PythonAnywhere 賬戶
要開始使用 PythonAnywhere,你首先需要建立一個賬戶:
- 轉到 PythonAnywhere 的計劃與定價頁面,然後選擇建立初學者賬戶按鈕。
- 用你的使用者名稱、電子郵件和密碼建立一個賬戶,確認條款和條件,然後選擇註冊。
- 然後你將被登入並重定向到 PythonAnywhere 儀表板:
https://www.pythonanywhere.com/user/<your_user_name>/。
從 GitHub 安裝庫
接下來,我們將開啟一個 Bash 提示符,設定一個虛擬環境,並從 GitHub 獲取本地圖書館的原始碼。我們還將配置預設資料庫並收集靜態檔案,以便它們可以由 PythonAnywhere 提供服務。
-
首先,透過選擇頂部應用程式欄中的Consoles來開啟控制檯管理螢幕。
-
然後選擇 Bash 連結來建立並啟動一個新的控制檯。

請注意,你建立的任何控制檯都會被儲存以供以後重複使用,連同其所有歷史記錄。上面的綠色箭頭顯示該賬戶有一個我們可以開啟的控制檯。
-
在控制檯中,輸入以下命令來建立一個名為 "env_local_library" 的 Python 3.10 虛擬環境,用於安裝本地圖書館的依賴項。
bashmkvirtualenv --python=python3.10 env_local_library這與設定 Django 開發環境中介紹的過程完全相同。我們可以給環境起任何名字,並且可以使用以下命令停用和重新啟用它:
bashdeactivate workon env_local_library -
接下來從 GitHub 獲取庫的原始碼。PythonAnywhere 希望你將應用程式安裝在以你的站點 URL 命名的資料夾中。
備註: 因為我們使用的是免費賬戶,你只能將你的賬戶命名為
<your_pythonanywhere_username>.pythonanywhere.com(例如,如果你的使用者名稱是“Odtsetseg”,你將不得不將本地圖書館的原始碼放入一個名為odtsetseg.pythonanywhere.com的資料夾中)。輸入以下命令將你的庫原始碼克隆到一個適當命名的資料夾中(你需要將使用者名稱值替換為你自己的名字):
bashgit clone https://github.com/<github_username>/django-locallibrary-tutorial.git <your_pythonanywhere_username>.pythonanywhere.com # Navigate into the new folder cd <your_pythonanywhere_username>.pythonanywhere.com -
使用
requirements.txt檔案安裝庫的依賴項:bashpip3 install -r requirements.txt -
在託管計算機上建立並配置一個 SQLite 資料庫(就像我們在開發期間做的那樣)。
bashpython manage.py migrate備註: 對於 Railway 的例子,我們將配置一個 Postgres 資料庫,並透過設定
DATABASE_URL環境變數來連線它。重要的是,migrate必須在配置使用哪個資料庫之後呼叫。 -
將所有靜態檔案收集到一個可以在生產環境中提供服務的位置:
bashpython manage.py collectstatic --no-input -
為訪問網站建立一個超級使用者(如Django 管理站點部分所述):
bashpython 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”),然後選擇儲存按鈕。
pythonimport 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()請注意,WSGI 檔案的作用是幫助 Gunicorn 伺服器找到本地圖書館應用程式。PythonAnywhere 希望這個檔案在這個位置,這就是為什麼不能使用專案中已有的 WSGI 檔案的原因。
-
向下滾動到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,你需要從一個環境檔案中讀取它們。我們已經為此做好了準備,所以我們只需要建立這個檔案。
步驟如下:
-
開啟一個 PythonAnywhere 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.com 並點選頂部工具欄中的登入連結。
- 在彈窗中選擇 GitHub,使用你的 GitHub 憑據登入。
- 然後你可能需要去你的電子郵件中驗證你的賬戶。
- 然後你將被登入到 Railway.com 儀表板:https://railway.com/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 將自動更新並重新部署你的應用程式)。
配置並連線一個 Postgres SQL 資料庫
接下來,我們需要建立一個 Postgres 資料庫,並將其連線到我們剛剛部署的 Django 應用程式。(如果你現在開啟網站,你會收到一個新的錯誤,因為無法訪問資料庫)。我們將把資料庫作為應用程式專案的一部分來建立,儘管你也可以在一個獨立的單獨專案中建立資料庫。
在 Railway 上,從網站頂部選單中選擇儀表板選項,然後選擇你的應用程式專案。在這個階段,它只包含一個用於你的應用程式的服務(可以選擇這個服務來設定變數和服務的其他細節)。設定按鈕可以選擇來更改專案範圍的設定。選擇新建按鈕,用於向專案新增服務。

當提示要新增的服務型別時,選擇資料庫。

然後選擇新增 PostgreSQL 開始新增資料庫。

Railway 隨後將在同一專案中配置一個包含空資料庫的服務。完成後,你現在將在專案檢視中看到應用程式和資料庫服務。

選擇 Web 服務,然後選擇變數選項卡。選擇新建變數,然後在變數名框中,選擇新增引用。向下滾動並選擇 DATABASE_URL(這是我們設定 locallibrary 從環境變數中讀取的變數名)。

然後選擇新增來新增變數引用,最後選擇部署(這會出現在一個彈窗中)。請注意,你也可以開啟 Postgres 資料庫,然後開啟其變數選項卡,然後複製變數過來。
如果你現在開啟專案,它應該會像在本地一樣顯示。但是請注意,目前還沒有辦法用資料填充圖書館,因為我們還沒有建立一個超級使用者賬戶。我們將使用我們本地計算機上的 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。最終的變數集應該如下所示:

除錯
Railway 客戶端提供了 logs 命令來顯示日誌的尾部(每個專案在網站上有更完整的日誌可用):
railway logs
如果這提供的資訊不夠,你需要開始研究Django 日誌。
總結
關於在生產環境中設定 Django 應用的教程到此結束,同時也是關於使用 Django 的系列教程的結尾。我們希望你覺得它們有用。你可以在GitHub 上檢視一個完整實現版本的原始碼。
下一步是閱讀我們最後幾篇文章,然後完成評估任務。
另見
-
部署 Django (Django 文件)
- 部署清單 (Django 文件)
- 部署靜態檔案 (Django 文件)
- 如何使用 WSGI 部署 (Django 文件)
- 如何將 Django 與 Apache 和 mod_wsgi 一起使用 (Django 文件)
- 如何將 Django 與 Gunicorn 一起使用 (Django 文件)
-
Railway 文件
-
DigitalOcean
-
Heroku 文件(類似設定概念)
- 為 Heroku 配置 Django 應用 (Heroku 文件)
- 在 Heroku 上開始使用 Django (Heroku 文件)
- Django 和靜態資產 (Heroku 文件)
- Django 中的併發和資料庫連線 (Heroku 文件)
- Heroku 是如何工作的 (Heroku 文件)
- Dyno 和 Dyno 管理器 (Heroku 文件)
- 配置和配置變數 (Heroku 文件)
- 限制 (Heroku 文件)
- 使用 Gunicorn 部署 Python 應用程式 (Heroku 文件)
- 使用 Django (Heroku 文件)