在ECS執行個體上部署Django專案,可通過Nginx分發靜態檔案,結合uWSGI管理應用進程,從而實現動靜分離,提升服務效能。
工作原理
瀏覽器向伺服器發送HTTP或HTTPS請求。
Nginx作為前端伺服器,接收傳入的請求。
靜態資源(如CSS、JavaScript、圖片)的請求,Nginx直接從本地提供檔案。可提升響應速度,並減輕Django應用的負載。
動態請求則轉寄至uWSGI伺服器。
uWSGI接收到Nginx轉寄的請求,將其傳遞給Django應用進行處理,實現負載平衡。
Django應用處理請求,執行商務邏輯(如資料庫查詢、模板渲染),返迴響應資料。
操作步驟
步驟一:準備資源
建立ECS執行個體。
前往執行個體購買頁。選擇自訂購買頁簽。
執行個體規格:推薦使用至少2 vCPU和4 GiB記憶體。
鏡像:Alibaba Cloud Linux 3。
網路和安全性群組:
網路:選擇已建立的Virtual Private Cloud。
公網IP:勾選分配公網 IPv4 地址。
安全性群組:選擇建立安全性群組並勾選HTTP (TCP:80)。
配置運行時環境。
安裝Nginx與Python開發套件(編譯uWSGI)。
預設源的Nginx版本過舊,有安全風險。添加Nginx官方源以安裝最新的穩定版本。
#添加Nginx官方源到系統中 sudo tee /etc/yum.repos.d/nginx.repo <<-'EOF' [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/8/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true EOF sudo yum install -y python3.8 python38-devel pcre-devel gcc make nginx #安裝Django和uWSGI sudo python3.8 -m pip install --upgrade pip wheel -i https://mirrors.aliyun.com/pypi/simple sudo python3.8 -m pip install "Django>=4.2,<5.0" "uwsgi>=2.0.23" -i https://mirrors.aliyun.com/pypi/simple建立logs,static,media目錄分別用於儲存日誌,靜態檔案和媒體檔案,建立/run/uwsgi目錄用於存放socket檔案。
sudo mkdir -p /srv/django-app/{logs,static,media} sudo mkdir -p /run/uwsgi
步驟二:部署Django應用
建立一個Django樣本專案。
推薦為專案建立Python虛擬環境,可以隔離專案依賴,避免不同專案間的包版本衝突。
sudo /usr/local/bin/django-admin startproject myproject /srv/django-app/修改專案設定檔
/srv/django-app/myproject/settings.py,以滿足生產環境的安全和效能要求。設定
DEBUG屬性為False。此操作可防止應用出錯時泄露敏感配置與代碼細節。設定
ALLOWED_HOSTS屬性為執行個體的公網IP地址。如果此列表為空白,應用將無法啟動。這是Django的一項內建安全機制。IP地址須作為字串包含在列表中,例如
['xxx.xxx.xxx.xxx']在檔案末尾添加
STATIC_ROOT = BASE_DIR / 'static',用於指定靜態檔案目錄。
同步樣本專案的靜態檔案至指定目錄(
STATIC_ROOT),以供Nginx直接存取。sudo python3.8 /srv/django-app/manage.py collectstatic --noinput執行資料庫遷移,在資料庫中建立儲存使用者等應用資料所需的表結構。
Django專案預設使用SQLite3資料庫,該配置不適用於生產環境。修改
myproject/settings.py檔案中的DATABASES設定,可將其替換為其他資料庫。sudo python3.8 /srv/django-app/manage.py migrate建立專案的管理員賬戶,用於後續登入Django管理後台。
sudo python3.8 /srv/django-app/manage.py createsuperuser
步驟三:配置uWSGI服務
建立uWSGI設定檔
/etc/django-app.ini。指定專案路徑、進程模型、socket檔案位置和記錄檔。processes參數可根據執行個體CPU核心數進行調整,建議設定為核心數 * 2建議使用非特權使用者運行服務,即使應用被攻破,攻擊者也無法獲得伺服器的最高許可權。
[uwsgi] # 專案配置 chdir = /srv/django-app module = myproject.wsgi:application # 進程配置 master = true processes = 4 threads = 2 # 網路與許可權配置 socket = /run/uwsgi/django-app.sock chmod-socket = 666 chown-socket = root:root vacuum = true # 安全與回合組態 uid = root gid = root die-on-term = true # 日誌配置 logto = /srv/django-app/logs/uwsgi.log在後台啟動 uWSGI 服務,使其在終端關閉後也能持續運行。
可使用
ps aux | grep uwsgi命令檢查uWSGI進程狀態。nohup /usr/local/bin/uwsgi --ini /etc/django-app.ini &(可選)使用systemd管理uWSGI服務,可以實現開機自啟和更可靠的服務管理。
建立啟動設定檔
/etc/systemd/system/uwsgi-django-app.service。[Unit] Description=uWSGI service for Django App After=network.target [Service] User=root Group=root RuntimeDirectory=uwsgi ExecStart=/usr/local/bin/uwsgi --ini /etc/django-app.ini Restart=always KillSignal=SIGQUIT Type=notify NotifyAccess=all [Install] WantedBy=multi-user.target啟動uWSGI服務並設定開機自啟。
sudo systemctl daemon-reload sudo systemctl start uwsgi-django-app sudo systemctl enable uwsgi-django-app檢查服務狀態。
sudo systemctl status uwsgi-django-app
步驟四:配置Nginx作為前端伺服器
將下方配置中的
<server_ip>替換為執行個體公網IP,並將內容儲存為Nginx設定檔/etc/nginx/conf.d/django-app.conf。# 定義一個 upstream,指向 uWSGI 的 socket 檔案 upstream django_backend { server unix:/run/uwsgi/django-app.sock; } server { listen 80; server_name <server_ip>; # 替換為公網IP charset utf-8; client_max_body_size 20M; # 靜態檔案服務 location /static/ { alias /srv/django-app/static/; } # 媒體檔案服務 location /media/ { alias /srv/django-app/media/; } # 代理所有其他請求到 Django 應用 location / { include /etc/nginx/uwsgi_params; uwsgi_pass django_backend; } }運行
nginx -t命令驗證Nginx設定檔文法是否正確。若輸出包含
syntax is ok和test is successful,則表示配置正確。重啟Nginx應用新配置並設定開機自啟。
sudo systemctl restart nginx sudo systemctl enable nginx訪問樣本專案登入頁面:
http://<ECS的公網IP地址>/admin。
生產應用建議
使用非特權使用者運行服務:建立一個無登入許可權的系統使用者來運行應用,可以有效隔離許可權,提升伺服器安全性。即使應用代碼存在漏洞被利用,攻擊者也無法獲得伺服器的root許可權。
#建立一個無登入許可權的系統使用者 (django-app) sudo useradd --system --shell /bin/false --home /srv/django-app django-app #應用目錄的所有權更改為django-app使用者。 sudo chown -R django-app:django-app /srv/django-app使用 Python 虛擬環境:為每個專案建立獨立的Python虛擬環境,可以隔離專案依賴,避免不同專案間的包版本衝突。這使得部署環境更加純淨、可預測,並且易於複現。
# 建立虛擬環境 python3.8 -m venv venv # 啟用虛擬環境 source venv/bin/activate
常見問題
訪問頁面顯示502 Bad Gateway
此錯誤通常表示Nginx無法與uWSGI正常通訊。
檢查uWSGI服務狀態:
systemctl status uwsgi-django-app。查看uWSGI日誌:
tail -f /srv/django-app/logs/uwsgi.log。檢查socket檔案是否存在及其許可權:
ls -l /run/uwsgi/django-app.sock。
訪問靜態檔案顯示403 Forbidden
此問題是由於 Nginx 進程沒有足夠的許可權讀取靜態檔案目錄。
確認Nginx的運行使用者(在Alibaba Cloud Linux上通常是
nginx)對/srv/django-app/static/目錄及其所有子檔案和子目錄具有讀取(r)和執行(x)許可權。
訪問頁面顯示500 Internal Server Error
此錯誤表示 Django 應用在處理請求時內部發生錯誤。
開啟偵錯模式定位問題:臨時將專案設定檔
settings.py中的DEBUG設定為True,然後重啟uWSGI服務並重新整理頁面。瀏覽器將顯示詳細的錯誤堆棧資訊,有助於快速定位問題。重要此操作僅限調試使用,問題解決後須將
DEBUG改回False,以防敏感資訊泄露。檢查uWSGI日誌:錯誤資訊同樣會被記錄在uWSGI的記錄檔中,通過查看日誌可以擷取Django拋出的具體錯誤。