介紹
Django是一個功能強大的Web架構,可以幫助您實作Python應用程式或網站。Django包含一個簡化的開發伺服器,用于在本地測試您的代碼,但是對于任何與生産相關的細節,都需要一個更安全,更強大的Web伺服器。
在本指南中,我們将示範如何在Ubuntu 18.04上安裝和配置某些元件以支援和服務Django應用程式。我們将設定PostgreSQL資料庫,而不是使用預設的SQLite資料庫。我們将配置Gunicorn應用程式伺服器以與我們的應用程式連接配接。然後,我們将設定Nginx以反向代理Gunicorn,讓我們可以通路其安全性和性能功能來為我們的應用程式提供服務。
先決條件和目标
為了完成本指南,您應該擁有一個新的Ubuntu 18.04伺服器執行個體,其中包含基本防火牆和配置了
sudo
權限的非root使用者。沒有伺服器的同學可以在這裡購買,不過我個人更推薦您使用免費的騰訊雲開發者實驗室進行試驗,學會安裝後再購買伺服器。在您的伺服器上啟用防火牆,如果您使用的是騰訊雲的CVM伺服器,您可以直接在騰訊雲控制台中的安全組進行設定。
我們将在虛拟環境中安裝Django。将Django安裝到特定于項目的環境中将允許單獨處理您的項目及其需求。
一旦我們啟動并運作了資料庫和應用程式,我們将安裝和配置Gunicorn應用程式伺服器。這将作為我們應用程式的接口,将用戶端請求從HTTP轉換為我們的應用程式可以處理的Python調用。然後,我們将在Gunicorn面前設定Nginx,以利用其高性能連接配接處理機制及其易于實作的安全功能。
讓我們開始吧。
從Ubuntu存儲庫安裝軟體包
要開始這個過程,我們将從Ubuntu存儲庫下載下傳并安裝我們需要的所有項目。稍後我們将使用Python包管理器
pip
安裝其他元件。
我們需要更新本地
apt
包索引,然後下載下傳并安裝包。我們安裝的軟體包取決于您的項目将使用哪個版本的Python。
如果您在Python 3中使用Django ,請鍵入:
sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl
複制
Django 1.11是支援Python 2的Django的最後一個版本。如果你正在開始新項目,強烈建議你選擇Python 3.如果你仍然需要使用Python 2,請輸入:
sudo apt update
sudo apt install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx curl
複制
這将安裝
pip
,後來建構Gunicorn所需的Python開發檔案,Postgres資料庫系統和與之互動所需的庫,以及Nginx Web伺服器。
建立PostgreSQL資料庫和使用者
我們将直接進入并為我們的Django應用程式建立資料庫和資料庫使用者。
預設情況下,Postgres使用稱為“對等身份驗證”的身份驗證方案進行本地連接配接。基本上,這意味着如果使用者的作業系統使用者名與有效的Postgres使用者名比對,則該使用者無需進一步身份驗證即可登入。
在Postgres安裝期間,建立了一個名為
postgres
的作業系統使用者,以對應
postgres
PostgreSQL管理使用者。我們需要使用此使用者來執行管理任務。我們可以使用sudo并使用
-u
選項傳遞使用者名。
鍵入以下内容登入互動式Postgres會話:
sudo -u postgres psql
複制
您将獲得PostgreSQL提示,我們可以在其中設定我們的要求。
首先,為您的項目建立一個資料庫:
CREATE DATABASE myproject;
複制
注意:每個Postgres語句必須以分号結尾,是以如果遇到問題,請確定指令以1結尾。
接下來,為我們的項目建立一個資料庫使用者。確定選擇安全密碼:
CREATE USER myprojectuser WITH PASSWORD 'password';
複制
之後,我們将為剛剛建立的使用者修改一些連接配接參數。這将加速資料庫操作,以便每次建立連接配接時都不必查詢和設定正确的值。
我們正在将Django期望的預設編碼設定為
UTF-8
。我們還将預設事務隔離方案設定為“read committed”,它阻止從未送出的事務中的讀取。最後,我們正在設定時區。預設情況下,我們的Django項目将設定為使用
UTC
。以下是Django項目本身的所有建議:
ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myprojectuser SET timezone TO 'UTC';
複制
現在,我們可以為新使用者提供管理新資料庫的權限:
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
複制
完成後,鍵入以下内容退出PostgreSQL提示符:
\q
複制
現在設定了Postgres,以便Django可以連接配接并管理其資料庫資訊。
為您的項目建立Python虛拟環境
現在我們有了資料庫,我們就可以開始準備其餘的項目需求。我們将在虛拟環境中安裝我們的Python需求,以便于管理。
為此,我們首先需要通路該
virtualenv
指令。我們可以使用
pip
來安裝這個。
如果您使用的是Python 3,請鍵入以下指令更新
pip
并安裝該軟體包:
sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv
複制
如果您使用的是Python 2,請鍵入以下指令更新
pip
并安裝該軟體包:
sudo -H pip install --upgrade pip
sudo -H pip install virtualenv
複制
随着
virtualenv
安裝,我們可以開始形成我們的項目。建立并移動到我們可以儲存項目檔案的目錄中:
mkdir ~/myprojectdir
cd ~/myprojectdir
複制
在項目目錄中,鍵入以下指令建立Python虛拟環境:
virtualenv myprojectenv
複制
這将在您的
myprojectdir
目錄中建立一個名為
myprojectenv
的目錄。在裡面,它将安裝本地版本的Python和
pip
的本地版本。我們可以使用它為我們的項目安裝和配置一個獨立的Python環境。
在我們安裝項目的Python需求之前,我們需要激活虛拟環境。您可以通過鍵入以下内容來執
source myprojectenv/bin/activate
複制
您的提示應更改為表明您現在在Python虛拟環境中運作。它看起來像這樣:
(myprojectenv)user@host:~/myprojectdir$
。
在您的虛拟環境處于活動狀态時,使用以下
pip
本地執行個體來安裝Django,Gunicorn和
psycopg2
PostgreSQL擴充卡:
注意:當虛拟環境被激活時(當您的提示位于其
(myprojectenv)
前面時),即使您使用的是Python3,也請使用
pip
而不是
pip3
. 無論Python是什麼版本,虛拟環境的工具副本始終都會被命名為
pip
。
pip install django gunicorn psycopg2-binary
複制
您現在應該擁有啟動Django項目所需的所有軟體。
建立和配置新的Django項目
安裝我們的Python元件後,我們可以建立實際的Django項目檔案。
建立Django項目
由于我們已經有了一個項目目錄,我們将告訴Django在這裡安裝檔案。它将使用實際代碼建立第二級目錄,這是正常的,并将管理腳本放在此目錄中。關鍵是我們明确定義目錄,而不是允許Django相對于我們目前目錄做出決定:
django-admin.py startproject myproject ~/myprojectdir
複制
此時,您的項目目錄(在我們的示例中為
~/myprojectdir
)應具有以下内容:
-
:Django項目管理腳本。~/myprojectdir/manage.py
-
:Django項目包。這應該包括~/myprojectdir/myproject/
,__init__.py
,settings.py
,和urls.py
檔案。wsgi.py
-
:我們之前建立的虛拟環境目錄。~/myprojectdir/myprojectenv/
調整項目設定
我們應該對新建立的項目檔案做的第一件事就是調整設定。在文本編輯器中打開設定檔案:
nano ~/myprojectdir/myproject/settings.py
複制
首先找到
ALLOWED_HOSTS
指令。這定義了伺服器的位址清單或可用于連接配接Django執行個體的域名。具有不在此清單中的主機頭的任何傳入請求都将引發異常。Django要求您将其設定為防止某類安全漏洞。
在方括号中,列出與Django伺服器關聯的IP位址或域名。每個項目都應該在引号中列出,條目用逗号分隔。如果您希望請求整個域和任何子域,請在條目的開頭添加一個句點。在下面的代碼段中,有一些注釋掉的示例用于示範:
注意:確定包含
localhost
并将其作為選項之一,因為我們将通過本地Nginx執行個體代理連接配接。
. . .
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']
複制
接下來,找到配置資料庫通路的部分。它将從
DATABASES
開始。該檔案中的配置适用于SQLite資料庫。我們已經為項目建立了PostgreSQL資料庫,是以我們需要調整設定。
使用PostgreSQL資料庫資訊更改設定。我們告訴Django使用我們用
pip
安裝的
psycopg2
擴充卡。我們需要提供資料庫名稱,資料庫使用者名,資料庫使用者的密碼,然後指定資料庫位于本地計算機上。您可以将
PORT
設定保留為空字元串:
. . .
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
. . .
複制
接下來,向下移動到檔案的底部,并添加一個設定,訓示應放置靜态檔案的位置。這是必要的,以便Nginx可以處理這些項目的請求。以下行告訴Django将它們放在基礎項目目錄中名為
static
的目錄中:
. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
複制
完成後儲存并關閉檔案。
完成初始項目設定
現在,我們可以使用管理腳本将初始資料庫模式遷移到PostgreSQL資料庫:
~/myprojectdir/manage.py makemigrations
~/myprojectdir/manage.py migrate
複制
鍵入以下内容為項目建立管理使用者:
~/myprojectdir/manage.py createsuperuser
複制
您必須選擇使用者名,提供電子郵件位址,然後選擇并确認密碼。
我們可以通過輸入以下内容将所有靜态内容收集到我們配置的目錄位置:
~/myprojectdir/manage.py collectstatic
複制
您必須确認操作。然後,靜态檔案将被放在項目目錄中名為
static
的目錄中。
如果您按照初始伺服器設定指南進行操作,則應該使用UFW防火牆來保護您的伺服器。為了測試開發伺服器,我們必須允許通路我們将要使用的端口。
鍵入以下指令為端口8000建立例外:
sudo ufw allow 8000
複制
最後,您可以使用以下指令啟動Django開發伺服器來測試我們的項目:
~/myprojectdir/manage.py runserver 0.0.0.0:8000
複制
在Web浏覽器中,通路後跟
:8000
的伺服器的域名或IP位址:
http://server_domain_or_IP:8000
複制
您應該看到預設的Django索引頁面:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAjM2EzLcd3LcJzLcJzdllmVldWYtl2Pn5GcugGeohna3djazgzLcNDO0EjMyEzLcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.png)
如果您追加
/admin
到位址欄中URL的末尾,系統将提示您輸入使用以下
createsuperuser
指令建立的管理使用者名和密碼:
進行身份驗證後,您可以通路預設的Django管理界面:
完成浏覽後,在終端視窗中按CTRL-C關閉開發伺服器。
測試Gunicorn服務項目的能力
在離開我們的虛拟環境之前,我們要做的最後一件事是測試Gunicorn以確定它可以為應用程式提供服務。我們可以通過輸入項目目錄并使用
gunicorn
來附加元件目的WSGI子產品來完成此操作:
cd ~/myprojectdir
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
複制
這将在運作Django開發伺服器的同一界面上啟動Gunicorn。您可以傳回并再次測試應用程式。
注意:管理界面不會應用任何樣式,因為Gunicorn不知道如何找到對此負責的靜态CSS内容。
我們通過使用Python的子產品文法指定Django的
wsgi.py
檔案的相對目錄路徑來傳遞Gunicorn子產品,該檔案是我們應用程式的入口點。在此檔案内部,定義了一個名為
application
的函數,用于與應用程式通信。
完成測試後,在終端視窗中按CTRL-C以停止Gunicorn。
我們現在已經完成了Django應用程式的配置。我們可以通過輸入以下指令退出虛拟環境:
deactivate
複制
将删除提示中的虛拟環境訓示器。
為Gunicorn建立系統的套接字和服務檔案
我們已經測試過Gunicorn可以與我們的Django應用程式進行互動,但是我們應該實作一種更強大的啟動和停止應用程式伺服器的方法。為此,我們将制作systemd服務和套接字檔案。
Gunicorn套接字将在啟動時建立,并将監聽連接配接。當發生連接配接時,systemd将自動啟動Gunicorn程序來處理連接配接。
首先為Gunicorn建立并打開一個具有
sudo
權限的systemd套接字檔案:
sudo nano /etc/systemd/system/gunicorn.socket
複制
在裡面,我們将建立一個描述套接字的
[Unit]
部分,一個定義套接字位置的
[Socket]
部分,以及一個確定在正确的時間建立套接字的
[Install]
部分:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
複制
完成後儲存并關閉檔案。
接下來,在文本編輯器中使用
sudo
權限為Gunicorn建立并打開systemd服務檔案。服務檔案名應與套接字檔案名比對,但擴充名除外:
sudo nano /etc/systemd/system/gunicorn.service
複制
從該
[Unit]
部分開始,該部分用于指定中繼資料和依賴項。我們将在此處描述我們的服務,并告訴init系統僅在達到網絡目标後啟動它。因為我們的服務依賴于套接字檔案中的套接字,是以我們需要包含一個
Requires
指令來訓示這種關系:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
複制
接下來,我們将打開該
[Service]
部分。我們将指定要在其下運作的使用者群組。我們将為該流程提供正常使用者帳戶所有權,因為它擁有所有相關檔案。我們将為
www-data
小組提供團體所有權,以便Nginx可以輕松地與Gunicorn進行交流。
然後,我們将映射工作目錄并指定用于啟動服務的指令。在這種情況下,我們必須指定Gunicorn可執行檔案的完整路徑,該檔案安裝在我們的虛拟環境中。我們将程序綁定到我們在
/run
目錄中建立的Unix套接字,以便程序可以與Nginx通信。我們将所有資料記錄到标準輸出,以便該
journald
過程可以收集Gunicorn日志。我們還可以在這裡指定任何可選的Gunicorn調整。例如,在這種情況下我們指定了3個工作程序:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
複制
最後,我們将添加一個
[Install]
部分。如果我們在啟動時啟動它,這将告訴systemd将此服務連結到什麼。我們希望在正常多使用者系統啟動并運作時啟動此服務:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
[Install]
WantedBy=multi-user.target
複制
這樣,我們的systemd服務檔案就完成了。立即儲存并關閉它。
我們現在可以啟動并啟用Gunicorn套接字。這将在現在和啟動時在
/run/gunicorn.sock
中建立套接字檔案。當連接配接到該套接字時,systemd将自動啟動
gunicorn.service
來處理它:
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
複制
我們可以通過檢查套接字檔案來确認操作是否成功。
檢查Gunicorn套接字檔案
檢查程序的狀态以确定它是否能夠啟動:
sudo systemctl status gunicorn.socket
複制
接下來,檢查
/run
目錄中是否存在該
gunicorn.sock
檔案:
file /run/gunicorn.sock
Output/run/gunicorn.sock: socket
複制
如果
systemctl status
指令訓示發生錯誤或者您在目錄中找不到該
gunicorn.sock
檔案,則表明無法正确建立Gunicorn套接字。輸入以下内容檢查Gunicorn套接字的日志:
sudo journalctl -u gunicorn.socket
複制
再繼續檢視您的
/etc/systemd/system/gunicorn.socket
檔案以解決任何問題。
測試套接字激活
目前,如果您隻啟動了該
gunicorn.socket
單元,則由于套接字尚未收到任何連接配接,是以
gunicorn.service
将不會處于活動狀态。您可以輸入以下指令來檢查:
sudo systemctl status gunicorn
● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: inactive (dead)
複制
要測試套接字激活機制,我們可以通過
curl
來鍵入以下内容來發送連接配接到套接字:
curl --unix-socket /run/gunicorn.sock localhost
複制
您應該在終端中看到應用程式的HTML輸出。這表明Gunicorn已經啟動并能夠為您的Django應用程式提供服務。您可以通過鍵入以下内容來驗證Gunicorn服務是否正在運作:
sudo systemctl status gunicorn
● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2018-07-09 20:00:40 UTC; 4s ago
Main PID: 1157 (gunicorn)
Tasks: 4 (limit: 1153)
CGroup: /system.slice/gunicorn.service
├─1157 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
├─1178 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
├─1180 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
└─1181 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
Jul 09 20:00:40 django1 systemd[1]: Started gunicorn daemon.
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Starting gunicorn 19.9.0
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Listening at: unix:/run/gunicorn.sock (1157)
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Using worker: sync
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1178] [INFO] Booting worker with pid: 1178
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1180] [INFO] Booting worker with pid: 1180
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1181] [INFO] Booting worker with pid: 1181
Jul 09 20:00:41 django1 gunicorn[1157]: - - [09/Jul/2018:20:00:41 +0000] "GET / HTTP/1.1" 200 16348 "-" "curl/7.58.0"
複制
如果輸出
curl
或輸出
systemctl status
,則說明出現問題,請檢查日志以擷取其他詳細資訊:
sudo journalctl -u gunicorn
複制
檢查
/etc/systemd/system/gunicorn.service
檔案是否存在問題。如果您對
/etc/systemd/system/gunicorn.service
檔案進行了更改,請重新加載守護程式以重新讀取服務定義并通過鍵入以下内容重新啟動Gunicorn程序:
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
複制
請確定在繼續之前解決上述問題。
将Nginx配置為代理傳遞給Gunicorn
現在Gunicorn已經建立,我們需要配置Nginx以将流量傳遞給程序。
首先在Nginx的
sites-available
目錄中建立并打開一個新的伺服器塊:
sudo nano /etc/nginx/sites-available/myproject
複制
在裡面,打開一個新的伺服器塊。我們将首先指定此塊應該偵聽正常端口80,并且它應該響應我們伺服器的域名或IP位址:
server {
listen 80;
server_name server_domain_or_IP;
}
複制
接下來,我們将告訴Nginx忽略找到圖示的任何問題。我們還将告訴它在哪裡可以找到我們在
~/myprojectdir/static
目錄中收集的靜态資産。所有這些檔案都有一個标準的URI字首“/ static”,是以我們可以建立一個位置塊來比對這些請求:
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/sammy/myprojectdir;
}
}
複制
最後,我們将建立一個
location / {}
塊來比對所有其他請求。在這個位置的内部,我們将包含Nginx安裝中包含的标準
proxy_params
檔案,然後我們将流量直接傳遞給Gunicorn套接字:
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/sammy/myprojectdir;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
複制
完成後儲存并關閉檔案。現在,我們可以通過将檔案連結到
sites-enabled
目錄來啟用該檔案:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
複制
鍵入以下内容測試您的Nginx配置是否存在文法錯誤:
sudo nginx -t
複制
如果沒有報告錯誤,請輸入以下指令重新啟動Nginx:
sudo systemctl restart nginx
複制
最後,我們需要在端口80上打開正常流量的防火牆。由于我們不再需要通路開發伺服器,我們也可以删除規則以打開端口8000:
sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'
複制
您現在應該可以轉到伺服器的域或IP位址來檢視您的應用程式。
注意:配置Nginx後,下一步應該是使用SSL / TLS保護伺服器的流量。這很重要,因為沒有它,所有資訊(包括密碼)都以純文字形式通過網絡發送。
如果你有域名,保護你網站的最簡單方法是使用騰訊雲SSL證書服務,它提供免費的可信證書。騰訊雲SSL證書安裝操作指南進行設定。
如果你沒有域名,建議您先去這裡注冊一個域名,您需要将域名解析到您的伺服器,您可以使用騰訊雲雲解析進行快速設定。
對Nginx和Gunicorn進行故障排除
如果最後一步未顯示您的應用程式,則需要對安裝進行故障排除。
Nginx顯示預設頁面而不是Django應用程式
如果Nginx的顯示預設頁,而不是代理到您的應用程式,它通常意味着你需要調整
/etc/nginx/sites-available/myproject
檔案中的 ,以指向您的伺服器的IP位址或域名。
Nginx使用
server_name
來确定用于響應請求的伺服器塊。如果您看到預設的Nginx頁面,則表明Nginx無法明确地将請求與伺服器塊比對,是以它将回退到定義在
/etc/nginx/sites-available/default
中的預設塊。
在您的項目的伺服器塊中的
server_name
必須更加具體的,而不是被選擇一個預設的伺服器子產品。
Nginx顯示502 Bad Gateway錯誤而不是Django應用程式
502錯誤表示Nginx無法成功代理請求。各種配置問題都表現為502錯誤,是以需要更多資訊才能正确排除故障。
查找更多資訊的主要位置是Nginx的錯誤日志。通常,這将告訴您在代理事件期間導緻問題的條件。鍵入以下内容,遵循Nginx錯誤日志:
sudo tail -F /var/log/nginx/error.log
複制
現在,在浏覽器中發出另一個請求以生成新的錯誤(嘗試重新整理頁面)。您應該看到寫入日志的新錯誤消息。如果您檢視該消息,它應該可以幫助您縮小問題範圍。
您可能會看到以下消息:
connect()到unix:/run/gunicorn.sock失敗(2:沒有這樣的檔案或目錄)
這表明Nginx無法在給定位置找到該
gunicorn.sock
檔案。您應該将在
/etc/nginx/sites-available/myproject
檔案中定義的
proxy_pass
位置與
gunicorn.socket
systemd單元生成的
gunicorn.sock
檔案的實際位置進行比較。
如果在
/run
目錄中找不到
gunicorn.sock
檔案,通常意味着systemd套接字檔案無法建立它。傳回檢查Gunicorn套接字檔案的部分,逐漸完成Gunicorn的故障排除步驟。
connect()到unix:/run/gunicorn.sock失敗(13:權限被拒絕)
這表明由于權限問題,Nginx無法連接配接到Gunicorn套接字。使用root使用者而不是
sudo
使用者執行該過程時,可能會發生這種情況。雖然systemd能夠建立Gunicorn套接字檔案,但Nginx無法通路它。
如果根目錄(
/
)和
gunicorn.sock
檔案之間的任何點上的權限有限,則會發生這種情況。我們可以通過将socket檔案的絕對路徑傳遞給
namei
指令來檢視套接字檔案及其每個父目錄的權限和所有權值:
namei -l /run/gunicorn.sock
Outputf: /run/gunicorn.sock
drwxr-xr-x root root /
drwxr-xr-x root root run
srw-rw-rw- root root gunicorn.sock
複制
輸出顯示每個目錄元件的權限。通過檢視權限(第一列),所有者(第二列)群組所有者(第三列),我們可以确定允許哪種類型的通路套接字檔案。
在上面的示例中,套接字檔案和通向套接字檔案的每個目錄都具有全局讀取和執行權限(目錄的權限列以
r-x
而不是
---
)結束。Nginx程序應該能夠成功通路套接字。
如果通向套接字的任何目錄沒有全局讀取和執行權限,則Nginx将無法在不允許全局讀取和執行權限的情況下通路套接字,或確定将組所有權授予Nginx所屬的組的。
Django顯示:“無法連接配接到伺服器:連接配接被拒絕”
嘗試在Web浏覽器中通路應用程式的某些部分時,您可能會從Django看到的一條消息是:
OperationalError at /admin/login/
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
複制
這表明Django無法連接配接到Postgres資料庫。鍵入以下指令確定Postgres執行個體正在運作:
sudo systemctl status postgresql
複制
如果不是,您可以通過鍵入以下指令啟動它并使其在啟動時自動啟動(如果尚未配置為啟動):
sudo systemctl start postgresql
sudo systemctl enable postgresql
複制
如果仍有問題,請確定
~/myprojectdir/myproject/settings.py
檔案中定義的資料庫設定正确。
進一步排除故
對于其他故障排除,日志可以幫助縮小根本原因。依次檢查每一個并查找訓示問題區域的消息。
以下日志可能會有所幫助:
- 鍵入以下指令檢查Nginx程序日志:
sudo journalctl -u nginx
- 鍵入以下指令檢查Nginx通路日志:
sudo less /var/log/nginx/access.log
- 鍵入以下指令檢查Nginx錯誤日志:
sudo less /var/log/nginx/error.log
- 鍵入以下指令檢查Gunicorn應用程式日志:
sudo journalctl -u gunicorn
- 鍵入以下指令檢查Gunicorn套接字日志:
sudo journalctl -u gunicorn.socket
在更新配置或應用程式時,可能需要重新啟動程序以根據更改進行調整。
如果您更新Django應用程式,可以通過鍵入以下指令重新啟動Gunicorn程序以擷取更改:
sudo systemctl restart gunicorn
複制
如果您更改了Gunicorn套接字或服務檔案,請重新加載守護程式并通過鍵入以下内容重新啟動該過程:
sudo systemctl daemon-reload
sudo systemctl restart gunicorn.socket gunicorn.service
複制
如果您更改Nginx伺服器塊配置,請通過鍵入以下内容來測試配置,然後測試Nginx:
sudo nginx -t && sudo systemctl restart nginx
複制
這些指令有助于在調整配置時擷取更改。
結論
在本指南中,我們在自己的虛拟環境中設定了一個Django項目。我們已經配置了Gunicorn來翻譯用戶端請求,以便Django可以處理它們。之後,我們設定Nginx作為反向代理來處理用戶端連接配接并根據用戶端請求提供正确的項目。
Django通過提供許多常見的部分使建立項目和應用程式變得簡單,使您可以專注于獨特的元素。通過利用本文中介紹的正常工具鍊,您可以輕松地為從單個伺服器建立的應用程式提供服務。
更多Ubuntu教程請前往騰訊雲+社群學習更多知識。
參考文獻:《How To Set Up Django with Postgres, Nginx, and Gunicorn on Ubuntu 18.04》