1. 程式人生 > >nginx + uwsgi + django部署

nginx + uwsgi + django部署

virtualenv 配置虛擬環境

檢測是否已安裝virtualenv

virtualenv --version

若沒有顯示版本號則表示沒有安裝virtualenv
安裝virtualenv

pip install virtualenv

建立虛擬環境
路徑可自選,也可放置專案目錄下
venv為虛擬環境名,可自定義

virtualenv venv

進入虛擬環境(需在venv當前目錄下操作)

source /venv/bin/activate

# 退出虛擬環境命令
deactivate

安裝專案相關依賴
(此操作需要提前提前生成requirements.txt依賴檔案)
插入簡單說下django依賴檔案如何生成

生成依賴檔案
pip freeze > requirements.txt

安裝依賴

pip install -r requirements.txt

如何檢視依賴列表

pip list

至於為什麼要用虛擬環境來部署,其中的原因若有疑問就自行谷歌吧。不僅僅是部署,每新建一個專案,都建議使用虛擬環境,好處大大的。

推薦一個很不錯的擴充套件庫virtualenvwrapper,挺方便,喜歡的小夥伴就趕緊上手吧。

下面就要開始正式的部署了,這篇教程以ubuntu為例
整個部署結構如下:
the web client <-> the web server(nginx) <-> the socket <-> uwsgi <-> Django
nginx做反向代理處理靜態檔案,減輕伺服器負載
同時也可以配置多臺伺服器做負載均衡(此篇部落格不超扯)
uwsgi處理後臺請求
ps:後面寫些系列部落格介紹下uwsgi和nginx等部署所需
ps:畢竟光講怎麼用,不說原理真是耍流氓

配置uwsgi

虛擬環境下安裝uwsgi

pip install uwsgi

# 若安裝失敗,可能是python依賴庫沒有安裝
# 執行以下命令
apt-get install python-dev

編寫測試指令碼
在專案目錄下新增test.py指令碼,新增如下內容

# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2

用test.py測試uwsgi

uwsgi --http :8000 --wsgi-file test.py

# 若跑不起來,可能需要新增引數
# 具體原因這裡不深究,歷史遺留
# 感興趣的同學可自行谷歌
uwsgi --plugin python,http --http :8000 --wsgi-file test.py

瀏覽器訪問localhost:8000檢視頁面是否顯示hello world
若正常顯示,則說明如下環節正常拉通
the web client <-> uWSGI <-> Python
接著先測試以下django專案自身能否跑通

python manage.py runserver 0.0.0.0:8000

確認沒問題後,用uwsgi拉通django

uwsgi --http :8000 --module mysite.wsgi

此處wsgi命名方式:專案名.wsgi
此wsgi檔案可在專案目錄中得主目錄下找到
確認正常執行,說明如下環節正常拉通

the web client <-> uWSGI <-> Django

配置nginx

安裝nginx

apt-get install nginx

測試nginx能否正常執行,啟動nginx

/etc/init.d/nginx start
# 或者
service nginx start

訪問瀏覽器80埠
開啟localhost:80
若顯示Welcome to nginx!則說明nginx正常執行
說明如下環節正常拉通

the web client <-> the web server

nginx預設佔用80埠
同時訪問公網ip,預設訪問得埠也是80
即可以直接訪問localhost,不需要加80埠號
ps:贈送一些常用nginx命令

# 重啟nginx
service nginx restart
# 檢視nginx執行狀態
service nginx status
# 停止nginx服務
service nginx stop

編寫nginx配置檔案(ubuntu下,centos路徑則不同)
nginx相關配置存放在/etc/nginx
先將uwsgi_params檔案複製到專案目錄下
uwsgi_params可在/etc/nginx下找到

cp /etc/nginx/uwsgi_params /path/to/your/project

然後在專案目錄下新建mysite_nginx.conf
配置檔名,自己記得住就好,保證可讀性
填入以下內容

# myproject_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
    # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
    server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name .example.com; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    # Django media
    location /media  {
        alias /path/to/your/mysite/media;  # your Django project's media files - amend as required
    }

    location /static {
        alias /path/to/your/mysite/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     /path/to/your/mysite/uwsgi_params; # the uwsgi_params file you installed
    }
}

寫好配置檔案後,需要將此配置檔案軟連結至nginx配置檔案目錄下
配置檔案則存放在/etc/nginx/sites-enabled

ln -s /path/to/your/mysite_nginx.conf /etc/nginx/sites-enabled/

# 舉例conf檔案路徑為/home/test/mysite/mysite_nginx.conf
# 命令就這麼寫
ln -s /home/test/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/

接下來拉通部署下靜態檔案
在django專案得的setting檔案中,新增下面一行內容:

STATIC_ROOT = os.path.join(BASE_DIR, "static/")

執行python命令

python manage.py collectstatic

此命令會將專案中得所有靜態檔案全部彙總到static目錄下
原因就是為了方便給nginx做反向代理時,可以快速得找到所請求得靜態檔案
現在可以測試以下nginx是否能夠正常訪問靜態檔案
重啟以下nginx

service nginx restart

任意在瀏覽器訪問一個media裡面得圖片檔案(沒圖片,就自己加一個)
比如訪問localhost:8000/media/test.png
若是正常顯示,那麼接下來得路就好走多了。
然而,意外往往時會發生的,訪問不到的就根據報錯來定位問題
同時藉助nginx日誌,來檢視問題的原因
nginx日誌路徑/var/log/nginx/error.log
一般情況下,由於許可權問題導致訪問失敗的可能性最大
這時候就需要修改專案所在目錄的許可權
所以專案部署的時候不要把程式碼放到/root等許可權敏感的目錄下
ok,往下走
這時候就需要拉通nginx和uwsgi了
接著用test.py測試一把

uwsgi --socket :8001 --wsgi-file test.py

訪問8000埠,沒有問題的話,說明以下環節也拉通了
the web client <-> the web server <-> the socket <-> uWSGI <-> Python
這時候舉例萬里長征真的就幾步路了
我們之前nginx使用的時tcp sokect轉發請求,也就是使用埠轉發
現在,換成unix socket轉發
unix socket相對tcp socket速度更快,節省埠資源
然而要是做負載均衡的話,就需要利用不同的埠轉發請求至處理伺服器了
不多說,修改nginx配置檔案

server unix:///path/to/your/mysite/mysite.sock; # for a file socket
# server 127.0.0.1:8001; # for a web port socket (we'll use this first)

然後重啟nginx
啟動uwsgi

uwsgi --socket mysite.sock --wsgi-file test.py

訪問8000埠,看到hello world,那就是勝利的曙光
然而這裡往往是會保許可權錯誤所以,出現許可權問題,就試試下面兩個命令
其實就加個兩個許可權引數

uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666
# 或者
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664

搞定這個問題後,就可以拉通整個部署結構了(這個許可權最保險^_^)

uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=666

好了,其實整個部署過程到這就可以結束了
但是在命令中加各種引數是不太好的一個編碼習慣
還是寫到配置檔案裡面去
在專案目錄下新建mysite_uwsgi.ini

# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /path/to/your/project
# Django's wsgi file
module          = project.wsgi
# the virtualenv (full path)
home            = /path/to/virtualenv

# process-related settings
# master
master          = true
# maximum number of worker processes
# 程序數設定與cpu核數相同,保證並行效能
processes       = 10
# the socket (use the full path to be safe
socket          = /path/to/your/project/mysite.sock
# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = true

然後用簡單的uwsgi命令,就能完成部署了

uwsgi --ini mysite_uwsgi.ini

ps:附贈一些相關專案狀態檢視命令

# 檢視某端口占用情況(80埠為例)
lsof -i:80
# 檢視uwsgi或者nginx程序
ps -ef | grep uwsgi
# 停止uwsgi主程序
pkill uwsgi
# 殺掉某程序只需要知道pid既可
kill pid