溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Python3 中怎么利用Nginx 部署一個(gè)Django 項(xiàng)目

發(fā)布時(shí)間:2021-06-22 16:33:46 來(lái)源:億速云 閱讀:285 作者:Leah 欄目:編程語(yǔ)言

這篇文章將為大家詳細(xì)講解有關(guān)Python3 中怎么利用Nginx 部署一個(gè)Django 項(xiàng)目,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

一、工作原理
Django 的部署可以有很多方式,采用 nginx + uwsgi 的方式是其中比較常見(jiàn)的一種方式。

在這種方式中,我們的通常做法是,將 nginx 作為服務(wù)器最前端,它將接收 web 的所有請(qǐng)求,統(tǒng)一管理請(qǐng)求。nginx 把所有靜態(tài)請(qǐng)求自己來(lái)處理(這是 nginx 的強(qiáng)項(xiàng))。然后,nginx 將所有非靜態(tài)請(qǐng)求通過(guò) uwsgi 傳遞給 Django,由 Django 來(lái)進(jìn)行處理,從而完成一次 web 請(qǐng)求。

可見(jiàn),uwsgi 的作用就類(lèi)似一個(gè)橋接器,起到橋梁的作用。

Linux 的強(qiáng)項(xiàng)是用來(lái)做服務(wù)器,所以,下面的整個(gè)部署過(guò)程我們選擇在 Ubuntu 16.04 下完成。

技術(shù)擴(kuò)展:

WSGI 是 Web Server Gateway Interface 的縮寫(xiě)。以層的角度來(lái)看,WSGI 所在層的位置低于 CGI。但與 CGI 不同的是 WSGI 具有很強(qiáng)的伸縮性且能運(yùn)行于多線程或多進(jìn)程的環(huán)境下,這是因?yàn)?WSGI 只是一份標(biāo)準(zhǔn)并沒(méi)有定義如何去實(shí)現(xiàn)。實(shí)際上 WSGI 并非 CGI,因?yàn)槠湮挥?web 應(yīng)用程序與 web 服務(wù)器之間,而 web 服務(wù)器可以是 CGI??梢岳斫鉃槭?Python 內(nèi)置的一個(gè)測(cè)試 web 服務(wù)器。

uWSGI 是一個(gè)Web服務(wù)器,它實(shí)現(xiàn)了 WSGI 協(xié)議、uwsgi、http 等協(xié)議。Nginx 中HttpUwsgiModule 的作用是與 uWSGI 服務(wù)器進(jìn)行交換。WSGI 是一種 Web 服務(wù)器網(wǎng)關(guān)接口。比如把 HTTP 協(xié)議轉(zhuǎn)化成 WSGI 協(xié)議,讓 Python 可以直接使用。

二、項(xiàng)目環(huán)境
操作系統(tǒng): Ubuntu 16.04

編程語(yǔ)言: Python 3.5.2

Web 框架: Django 2.0.3

Web 服務(wù)器: uWSGI 2.0.17

Web 服務(wù)器: Nginx 1.10.3

具體的安裝這里不做詳述,Ubuntu 使用 apt-get 安裝特別方便。

sudo apt-get install python3
sudo apt-get install python3-pip
sudo apt-get install nginx
1
2
3
Nginx 安裝成功在瀏覽器中輸入 127.0.0.1,出現(xiàn) “Welcome to nginx!”表示安裝成功。

三、uWSGI 安裝配置
安裝
sudo pip3 install uwsgi
1
測(cè)試
創(chuàng)建 test.py 文件

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b'Hello World']
1
2
3
4
5
6
通過(guò) uWSGI 運(yùn)行該文件

uwsgi --http :8000 --wsgi-file test.py
1
在瀏覽器中輸入 127.0.0.1:8000,出現(xiàn) “Hello World”表示安裝成功。

四、Django 與 uWSGI 之間的通信
安裝 Django
sudo pip3 install Django==2.0.3
1
創(chuàng)建 Django 項(xiàng)目
django-admin startproject myweb
1
我的 Django 項(xiàng)目位置為:/home/setup/myweb

uwsgi --http :8000 --chdir /home/setup/myweb --wsgi-file myweb/wsgi.py --master --processes 4 --threads 2 --stats 127.0.0.1:8001
1
常用選項(xiàng)
http: 協(xié)議類(lèi)型和端口號(hào)

processes: 開(kāi)啟的進(jìn)程數(shù)量

workers: 開(kāi)啟的進(jìn)程數(shù)量,等同于 processes

chdir: 指定運(yùn)行目錄

wsgi-file: 載入 wsgi-file

stats: 在指定的地址上,開(kāi)啟狀態(tài)服務(wù)

threads: 運(yùn)行線程。由于 GIL 的存在,我覺(jué)得這個(gè)真心沒(méi)啥用。

master: 允許主進(jìn)程存在

daemonize: 使進(jìn)程在后臺(tái)運(yùn)行,并將日志打到指定的日志文件或者 udp 服務(wù)器(daemonize uWSGI)。實(shí)際上最常用的,還是把運(yùn)行記錄輸出到一個(gè)本地文件上。

pidfile: 指定pid文件的位置,記錄主進(jìn)程的pid號(hào)。

vacuum: 當(dāng)服務(wù)器退出的時(shí)候自動(dòng)清理環(huán)境,刪除 unix socket 文件和 pid 文件

五、Nginx、uWSGI、Django 之間的通信
接下來(lái),我們要將三者結(jié)合起來(lái)

1. 配置 Django 和 uWSGI
先在 Django 項(xiàng)目根目錄下新建一個(gè) uWSGI 的配置文件 uwsgi.ini

cd myweb
touch uwsgi.ini 
1
2
此時(shí) Django 項(xiàng)目的目錄文件結(jié)構(gòu)如下:

myweb/
├── manage.py
├── myweb
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-35.pyc
│   │   └── settings.cpython-35.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── uwsgi.ini
1
2
3
4
5
6
7
8
9
10
11
在我們通過(guò) Django 創(chuàng)建 myweb 項(xiàng)目時(shí),在子目錄 myweb 下已經(jīng)幫我們生成的 wsgi.py文件。所以,我們只需要再創(chuàng)建 uwsgi.ini 配置文件即可。

uwsgi 支持多種類(lèi)型的配置文件,如 xml、ini 等。此處,使用 ini 類(lèi)型的配置。

接下來(lái)打開(kāi)剛剛創(chuàng)建好的配置文件 uwsgi.ini 添加如下配置:

[uwsgi]

socket = :8888
chdir           = /home/setup/myweb
module          = myweb.wsgi
master          = true
processes       = 4
vacuum          = true
1
2
3
4
5
6
7
8
這個(gè)配置,其實(shí)就相當(dāng)于在上一小節(jié)中通過(guò) wsgi 命令,后面跟一堆參數(shù)的方式,給文件化了。

socket: 指定項(xiàng)目執(zhí)行的端口號(hào)。

chdir: 指定項(xiàng)目的目錄。

module: module = hello.wsgi 可以這么來(lái)理解。對(duì)于 uwsgi.ini 文件而言,與它同級(jí)目錄有一個(gè) myweb 目錄,這個(gè)目錄下有一個(gè) wsgi.py 文件。

其它幾個(gè)參數(shù),可以參考上一小節(jié)中參數(shù)的介紹。

接下來(lái),通過(guò) uwsgi 命令讀取 uwsgi.ini 文件啟動(dòng)項(xiàng)目

uwsgi --ini uwsgi.ini
1
運(yùn)行結(jié)果:

setup@labideas-data:~/myweb$ uwsgi --ini uwsgi.ini
[uWSGI] getting INI configuration from uwsgi.ini
*** Starting uWSGI 2.0.17 (64bit) on [Tue Mar 20 11:11:30 2018] ***
compiled with version: 5.4.0 20160609 on 19 March 2018 09:13:12
os: Linux-4.4.0-105-generic #128-Ubuntu SMP Thu Dec 14 12:42:11 UTC 2017
nodename: labideas-data
machine: x86_64
clock source: unix
detected number of CPU cores: 4
current working directory: /home/setup/hello
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
chdir() to /home/setup/hello
your processes number limit is 64049
your memory page size is 4096 bytes
detected max file descriptor number: 65535
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address :8888 fd 3
Python version: 3.5.2 (default, Nov 23 2017, 16:37:01)  [GCC 5.4.0 20160609]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x1f73aa0
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 364520 bytes (355 KB) for 4 cores
*** Operational MODE: preforking ***
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x1f73aa0 pid: 7097 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 7097)
spawned uWSGI worker 1 (pid: 7099, cores: 1)
spawned uWSGI worker 2 (pid: 7100, cores: 1)
spawned uWSGI worker 3 (pid: 7101, cores: 1)
spawned uWSGI worker 4 (pid: 7102, cores: 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
注意查看uwsgi的啟動(dòng)信息,如果有錯(cuò),就要檢查配置文件的參數(shù)是否設(shè)置有誤。

2. 配置 Nginx
Nginx 默認(rèn)的配置文件都在 /etc/nginx 目錄下

setup@labideas-data:/etc/nginx$ ll
total 64
drwxr-xr-x  6 root root 4096 Mar 20 09:37 ./
drwxr-xr-x 95 root root 4096 Mar 19 19:56 ../
drwxr-xr-x  2 root root 4096 Mar 19 20:13 conf.d/
-rw-r--r--  1 root root 1077 Feb 12  2017 fastcgi.conf
-rw-r--r--  1 root root 1007 Feb 12  2017 fastcgi_params
-rw-r--r--  1 root root 2837 Feb 12  2017 koi-utf
-rw-r--r--  1 root root 2223 Feb 12  2017 koi-win
-rw-r--r--  1 root root 3957 Feb 12  2017 mime.types
-rw-r--r--  1 root root 1919 Mar 20 09:33 nginx.conf
-rw-r--r--  1 root root  180 Feb 12  2017 proxy_params
-rw-r--r--  1 root root  636 Feb 12  2017 scgi_params
drwxr-xr-x  2 root root 4096 Mar 20 10:00 sites-available/
drwxr-xr-x  2 root root 4096 Mar 19 14:59 sites-enabled/
drwxr-xr-x  2 root root 4096 Mar 19 14:59 snippets/
-rw-r--r--  1 root root  664 Feb 12  2017 uwsgi_params
-rw-r--r--  1 root root 3071 Feb 12  2017 win-utf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
我們需要進(jìn)入 /etc/nginx/sites-available 目錄下進(jìn)行配置 default 文件(有些 Linux 發(fā)行版的配置文件是在 /etc/nginx/nginx.conf 下,還有一些在其他地方,這里我們以 Ubuntu 16.04 為準(zhǔn))。

將原有配置文件進(jìn)行備份,并打開(kāi) nginx 配置文件

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
sudo vi /etc/nginx/sites-available/default
1
2
將默認(rèn)的 80 端口號(hào)改成其它端口號(hào),如 8080。因?yàn)槟J(rèn)的 80 端口號(hào)很容易被其它應(yīng)用程序占用,而且我們配置我們自己的 Django 項(xiàng)目也需要用到默認(rèn)端口。

# Django 2.0 項(xiàng)目部署
server {

    listen          80; 
    server_name     data.labideas.cn 
    charset         UTF-8;
    access_log      /var/log/nginx/myweb_access.log;
    error_log       /var/log/nginx/myweb_error.log;

    client_max_body_size 75M;

    location / { 

        include uwsgi_params;
        uwsgi_pass 127.0.0.1:8888;
        uwsgi_read_timeout 2;
    }   

    location /static {

        expires 30d;
        autoindex on; 
        add_header Cache-Control private;
        alias /home/setup/myweb/static/;
    }   
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
listen: 指定的是 nginx 代理 uwsgi 對(duì)外的端口號(hào)。

server_name: 網(wǎng)上大多資料都是設(shè)置的一個(gè)網(wǎng)址(例,www.baidu.com,如果指定的是 localhost 或 127.0.0.1 則只能在本機(jī)訪問(wèn)。

那么 nginx 到底是如何 uwsgi 產(chǎn)生關(guān)聯(lián)的呢?現(xiàn)在看來(lái)大概最主要的就是這兩行配置。

include uwsgi_params;
uwsgi_pass 127.0.0.1:8888;
1
2
include 必須指定為 uwsgi_params。而 uwsgi_pass 指的是本機(jī) IP 和端口號(hào),并且要與 myweb_uwsgi.ini 配置文件中的 IP 和端口號(hào)必須保持一致。

現(xiàn)在重新啟動(dòng) nginx

sudo /etc/init.d/nginx restart
1
然后瀏覽器訪問(wèn) 127.0.0.1

Invalid HTTP_HOST header: 'data.labideas.cn'. You may need to add 'data.labideas.cn' to ALLOWED_HOSTS.
[pid: 7924|app: 0|req: 1/1] 114.249.204.30 () {40 vars in 658 bytes} [Tue Mar 20 06:16:28 2018] GET / => generated 54903 bytes in 41 msecs (HTTP/1.1 400) 1 headers in 53 bytes (1 switches on core 0)
1
2
在 uWSGI 后臺(tái)就可以看到有信息輸出。通過(guò) IP 和端口號(hào)的指向,請(qǐng)求應(yīng)該是先到 nginx 的,如果你在頁(yè)面上執(zhí)行一些請(qǐng)求,就會(huì)看到,這些請(qǐng)求最終會(huì)轉(zhuǎn)到 uwsgi 來(lái)處理。

最后我們將 uWSGI 配置為開(kāi)機(jī)自啟

打開(kāi) sudo vi /etc/rc.local 將

uwsgi --ini /home/setup/myweb/uwsgi.ini &
1
添加到文件中

注意要添加到 exit 0 之前,& 表示該服務(wù)是在后臺(tái)執(zhí)行。

六、遇到的問(wèn)題
在配置過(guò)程中,總會(huì)遇到各種各樣的問(wèn)題,這里我將最常用的幾項(xiàng)問(wèn)題羅列出來(lái),希望能幫到你。

1. Django 啟動(dòng)報(bào)錯(cuò)
setup@labideas-data:~/myweb$ python3 manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).

You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

March 20, 2018 - 06:28:52
Django version 2.0.3, using settings 'myweb.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
1
2
3
4
5
6
7
8
9
10
11
12
創(chuàng)建一個(gè)新項(xiàng)目,利用 Django 本身的測(cè)試服務(wù)器啟動(dòng),會(huì)出現(xiàn)上述的錯(cuò)誤。這是因?yàn)槟愕捻?xiàng)目中有些默認(rèn)數(shù)據(jù)并沒(méi)有遷移到數(shù)據(jù)庫(kù)中。

解決辦法:

將數(shù)據(jù)遷移到數(shù)據(jù)庫(kù)中

python3 manage.py migrate
1
2. uwsgi 啟動(dòng)報(bào)錯(cuò)
在啟動(dòng) uwsgi 的時(shí)候,在啟動(dòng)信息中如果有下面的錯(cuò)誤提示:

!!! no internal routing support, rebuild with pcre support !!!
1
是依賴(lài)有問(wèn)題

解決辦法:

卸載 uwsgi,注意此時(shí)卸載,pip 會(huì)有緩存留在系統(tǒng)里

pip uninstall uwsgi
1
安裝 pcre 依賴(lài)庫(kù)

centos 安裝

sudo yum install pcre pcre-devel pcre-static
1
ubuntu 安裝

sudo apt-get install libpcre3 libpcre3-dev
1
重新安裝 uwsgi,不走 pip 緩存

pip install uwsgi -I --no-cache-dir
1
再次啟動(dòng) uwsgi,已經(jīng)沒(méi)有 !!! no internal routing support, rebuild with pcre support !!! 的報(bào)錯(cuò)了。

3. 端口報(bào)錯(cuò)
有時(shí)候進(jìn)過(guò)多次配置,啟動(dòng) Django 和 uWSGI 可能會(huì)出現(xiàn)如下報(bào)錯(cuò)

Error: That port is already in use
1
這是端口號(hào)已被占用,是 servr 已經(jīng)在運(yùn)行了,也有可能在后臺(tái)運(yùn)行或者是你停掉可 Django 但是,進(jìn)程資源和端口號(hào)并沒(méi)有釋放掉。

解決辦法:

找到該進(jìn)程 kill 掉即可

sudo ps aux | grep uwsgi
sudo kill -9 PID
1
2
或者最簡(jiǎn)單的解決方法就是直接殺掉

sudo fuser -k 8000/tcp
1
這樣和端口 8000 相關(guān)的進(jìn)程就都死掉了

4. 公網(wǎng)端口安全組屏蔽
還有一些情況,感覺(jué)明明所有東西都配置好了,還檢查了好多遍。本地沒(méi)有一丁點(diǎn)問(wèn)題,但是一上線就日了狗了,總是報(bào)“服務(wù)器未響應(yīng)”等錯(cuò)誤,或者 localhost 能訪問(wèn),但是就是使用域名或外網(wǎng)訪問(wèn)不了,氣的都想砸電腦…這又是怎么一回事呢?

項(xiàng)目在正式的環(huán)境中上線,一定是在公網(wǎng)上的,有時(shí)候我們會(huì)選擇云服務(wù)器,這里以阿里云服務(wù)器為例,我們需要為其開(kāi)放對(duì)應(yīng)的端口號(hào)。

聰明的同學(xué)可能已經(jīng)有所覺(jué)察,為什么上圖中并沒(méi)有 uwsgi.ini 文件中 8888 的端口號(hào)呢?

這是因?yàn)?,阿里云的安全組規(guī)則端口是對(duì)外屏蔽的,我們 Nginx 和 uWSGI 之間通信的 socket 端口號(hào) 8888 是在內(nèi)網(wǎng)環(huán)境中,所以不受影響。

5. 正式上線模式
因?yàn)槲覀冊(cè)趯?shí)際開(kāi)發(fā)的時(shí)候,需要用到 DEBUG 模式,但是在正式上線的時(shí)候我們需要關(guān)閉 DEBUG 模式。

打開(kāi) Django 項(xiàng)目中的 settings.py 配置文件

DEBUG = True
1
修改為

DEBUG = False
1

ALLOWED_HOSTS = []
1
修改為

ALLOWED_HOSTS = ['data.labideas.cn']
1
或者

ALLOWED_HOSTS = ['*']
1
建議不使用通配符 *,添加具體的域名即可!

6. Admin 管理界面樣式表丟失
曾幾何時(shí),Admin 是檢驗(yàn) Django 是否成功安裝的標(biāo)準(zhǔn)。但是在正式環(huán)境中,經(jīng)常會(huì)遇到樣式表丟失的問(wèn)題。為什么會(huì)這樣呢?

這是因?yàn)?Nginx 在正式環(huán)境中,找不到 Django 項(xiàng)目中的靜態(tài)文件。

解決辦法:

① 在 Django 項(xiàng)目中新建一個(gè) static 目錄,用于放置一些靜態(tài)文件

② 打開(kāi) Django 項(xiàng)目中的 settings.py 配置文件

添加一行

STATIC_ROOT = '/home/setup/myweb/static/'
1
將 STATIC_ROOT 指向存放靜態(tài)文件的 static 目錄

③ 從 Django 資源包中復(fù)制必須的靜態(tài)文件到 STATIC_ROOT 指向的 static 目錄中,這其中包括 admin 界面所必須的樣式表(style)、圖片(image)及腳本(js)等。

python3 manage.py collectstatic
1
需要注意的是,假如不做第 ① 步的話(huà),直接運(yùn)行這個(gè)命令會(huì)導(dǎo)致錯(cuò)誤發(fā)生。

④ 修改 Nginx 配置文件

location /static {

    expires 30d;
    autoindex on; 
    add_header Cache-Control private;
    alias /home/setup/html/data/static/;
}

將 alias 也指向存放靜態(tài)文件的 static 目錄,需要和 Django 項(xiàng)目中的 settings.py 配置文件中的 STATIC_ROOT 指向目錄保持一致。

⑤ 重啟 uWSGI 和 Nginx

# 殺掉 uwsgi.ini 進(jìn)程
ps aux | grep uwsgi | grep -v grep | awk '{print $2}' | xargs kill -9
uwsgi --ini /home/setup/html/data/uwsgi.ini &

sudo /etc/init.d/nginx restart

關(guān)于Python3 中怎么利用Nginx 部署一個(gè)Django 項(xiàng)目就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI