一、必要前提
1.1 准備知識
- django
一個基於python的開源web框架,請確保自己熟悉它的框架目錄結構。
- uWSGI
一個基於自有的uwsgi協議、wsgi協議和http服務協議的web網關
- nginx
常用高性能代理服務器
- wsgi.py
1 django項目攜帶的一個wsgi接口文件 2 如果項目名叫destiny的話,此文件就位於[destiny/destiny/wsgi.py]
1.2 相關資料
wsgi:一種實現python解析的通用接口標准/協議,是一種通用的接口標准或者接口協議,實現了python web程序與服務器之間交互的通用性。
利用它,web.py或bottle或者django等等的python web開發框架,就可以輕松地部署在不同的web server上了;
uwsgi:同WSGI一樣是一種通信協議
uwsgi協議是一個uWSGI服務器自有的協議,它用於定義傳輸信息的類型,它與WSGI相比是兩樣東西。
uWSGI :一種python web server或稱為Server/Gateway
uWSGI類似tornadoweb或者flup,是一種python web server,uWSGI是實現了uwsgi和WSGI兩種協議的Web服務器,負責響應python 的web請求。
因為apache、nginx等,它們自己都沒有解析動態語言如php的功能,而是分派給其他模塊來做,比如apache就可以說內置了php模塊,讓人感覺好像apache就支持php一樣。
uWSGI實現了wsgi協議、uwsgi協議、http等協議。 Nginx中HttpUwsgiModule的作用是與uWSGI服務器進行交換。
1.3 項目流程
其實網上很多教程,都是關於uwsgi+nginx部署django的,StackOverflow也有一些解決常見錯誤的方法,但是部署還是容易出問題,新手難解決。
歸根到底是自己不了解整個項目的流程。教程都只教方法,但為什么這樣部署,這樣部署有什么好處,每個組件都起什么作用卻只字不提。致使只要部署稍微有那么一點不同,就無可是從了。
所以說,項目流程和每個組件的用途才是此次部署最重要的部分。
1 首先客戶端請求服務資源, 2 nginx作為直接對外的服務接口,接收到客戶端發送過來的http請求,會解包、分析, 3 如果是靜態文件請求就根據nginx配置的靜態文件目錄,返回請求的資源, 4 如果是動態的請求,nginx就通過配置文件,將請求傳遞給uWSGI;uWSGI 將接收到的包進行處理,並轉發給wsgi, 5 wsgi根據請求調用django工程的某個文件或函數,處理完后django將返回值交給wsgi, 6 wsgi將返回值進行打包,轉發給uWSGI, 7 uWSGI接收后轉發給nginx,nginx最終將返回值返回給客戶端(如瀏覽器)。 8 *注:不同的組件之間傳遞信息涉及到數據格式和協議的轉換
作用:
1. 第一級的nginx並不是必須的,uwsgi完全可以完成整個的和瀏覽器交互的流程;
2. 在nginx上加上安全性或其他的限制,可以達到保護程序的作用;
3. uWSGI本身是內網接口,開啟多個work和processes可能也不夠用,而nginx可以代理多台uWSGI完成uWSGI的負載均衡;
4. django在debug=False下對靜態文件的處理能力不是很好,而用nginx來處理更加高效。
二、安裝與配置
首先,確保你已經安裝好了nginx並可以正常使用。
其次,確保自己安裝完成了python,並已經完成了pip的安裝。如果沒有,請先安裝。
接着,別忘了確認自己項目所需的django已經完成安裝並正常工作。
沒有的話參考以下命令安裝django , 建立一個工程或利用已經寫好的工程,打開瀏覽器,輸入部署地址(如:http://127.0.0.1:8000/)(或http://內網ip:8000、或http://外網ip:8000)測試,確認是否可正常打開瀏覽。
1 安裝:sudo pip install django==1.10
2 測試:python manage.py runserver 0.0.0.0:8000
上面的工作都完成了,接着安裝uWSGI
1 sudo pip install uwsgi
測試uWSGI: 新建文件test.py,寫入以下內容
1 def application(env, start_response): 2 start_response('200 OK', [('Content-Type','text/html')]) 3 return "Hello World"
運行
1 sudo uwsgi --http 0.0.0.0:8000 --wsgi-file test.py
如果端口占用,使用
1 lsof -i :8000
列出占用端口的程序的pid號,並使用以下命令殺掉所有占用端口的程序
1 sudo kill -9 pid
然后瀏覽 http://127.0.0.1:8000(或http://內網ip:8000、或http://外網ip:8000)查看效果,有”Hello World”輸出即安裝成功。
下一步,建立工程單獨的nginx配置文件
首先確認自己准確的知道nginx的默認配置文件目錄(nginx.conf)的路徑,如果不清楚,請使用如下命令獲取:
1 nginx -t
大概會列出以下類似信息:
1 nginx: the configuration file /etc/nginx/conf/nginx.conf syntax is ok 2 nginx: configuration file /etc/nginx/conf/nginx.conf test is successful
里面說明了nginx默認配置文件的路徑是:/etc/nginx/conf/nginx.conf;
然后,確保nginx.conf的同目錄下有uwsgi_params文件(/etc/nginx/conf/uwsgi_params),沒有的話根據鏈接獲取, 后面要用到。
在自己的工程目錄下,建立如destiny.conf(/wwwroot/destiny/destiny.conf)的配置文件;復制nginx.conf里面全部的內容,全部寫入destiny.conf中。
然后按照下面寫的,把destiny.conf配置文件中的server段部分全部替換掉。
1 server { 2 listen 80; 3 server_name localhost; 4 charset utf-8; 5 access_log /wwwroot/destiny/nginx_access.log; 6 error_log /wwwroot/destiny/nginx_error.log; 7 client_max_body_size 75M; 8
9
10 location /static { 11 alias /wwwroot/destiny/destiny/static; 12 } 13
14 location / { 15 include /etc/nginx/conf/uwsgi_params; 16 uwsgi_pass 127.0.0.1:9090; 17 } 18 }
其中的 listen 80代表服務器開放80端口;
location [目錄名]代表項目路徑的引導;
access_log 和error_log是定義nginx訪問日志和錯誤日志的存放路徑。
“location /static”中的”/static”是自己定義的項目引用靜態文件時,瀏覽器中顯示的靜態資源所在的根目錄名;這樣的話,用戶在瀏覽器中查看到的所有image、css或js資源都是處在http://127.0.0.1/static下的。
django靜態文件的絕對路徑是根據自己的實際情況來確定的,一般在自己的django的app名/static目錄下,或自己python manage.py collectstatic后的路徑下。像我的是在/wwwroot/destiny/destiny/static根目錄下。
“location /”是指訪問項目根目錄時,nginx要做的事。其中需要指定 uwsgi_params文件的絕對路徑,上面已經提到了;如果還有media文件之類的靜態目錄,仿照static的寫法,自己補充。
127.0.0.1:9090是指uWSGI綁定的監聽地址,這里使用了9090端口。
需要注意的是,請確認自己django的靜態文件目錄所有者是www用戶,如果不是,請用以下命令更改靜態目錄權限歸屬者:
1 sudo chown -R www:www /wwwroot/destiny/destiny/static
下面接着建立uWSGI的配置文件,在自己工程目錄下創建uwsgi.ini文件,寫入以下內容
1 [uwsgi] 2 socket = 127.0.0.1:9090 3 chdir=/wwwroot/destiny 4 module=destiny.wsgi 5 master = true 6 processes=2 7 threads=2 8 max-requests=2000 9 chmod-socket=664 10 vacuum=true 11 daemonize = /wwwroot/destiny/uwsgi.log
其中的socket字段值”127.0.0.1:9090”必須要和上面寫的density.conf配置文件中的uWSGI監聽地址完全一樣;
chdir指自己工程的絕對路徑;
module指的是wsgi.py在自己工程中的相對路徑,”.”指代一層目錄;我的django工程的wsgi.py文件是在”/wwwroot/destiny/destiny/wsgi.py”,所以寫成destiny.wsgi;
daemonize指定uWSGI日志的存儲路徑。
好了,現在理一下路徑:
1 工程路徑: /wwwroot/destiny 2 工程靜態文件路徑: /wwwroot/destiny/destiny/static 3 wsgi.py的路徑: /wwwroot/destiny/destiny/wsgi.py 4 uwsgi.ini的路徑: /wwwroot/destiny/uwsgi.ini 5 uwsgi日志路徑: /wwwroot/destiny/uwsgi.log 6 destiny.conf的路徑: /wwwroot/destiny/destiny.conf 7 uwsgi_params的路徑: /etc/nginx/conf/uwsgi_params 8 nginx訪問日志路徑: /wwwroot/destiny/nginx_access.log 9 nginx錯誤日志路徑: /wwwroot/destiny/nginx_error.log
可以發現,我幾乎把所有有關工程的配置文件和日志文件都放在工程目錄下了,方便后期維護與查錯。
啟動uWSGI
1 sudo uwsgi --ini /wwwroot/destiny/destiny.ini
啟動nginx
在這之前,我們要先去nginx配置文件的根目錄拷貝mime.types(/etc/nginx/conf/mime.types)到工程目錄(/wwwroot/destiny/mime.types),和destiny.conf放在一起。
否則用配置文件啟動nginx會報錯:
1 nginx: [emerg] open() "/**/**/**/mime.types" failed (2: No such file or directory)
當然,如果不想拷貝mime.types文件,也可以將配置文件中“include mime.types;”一項,改成絕對路徑“include /etc/nginx/conf/mime.types;”
如果nginx已經開啟,先關閉nginx(service nginx stop或nginx -s stop),再執行以下命令:
1 nginx -c /wwwroot/destiny/destiny.conf
這里的-c 表示加載配置文件啟動
三、后記
到這里,工作基本就做完了,可以打開瀏覽器,輸入自己項目的IP地址,如http://127.0.0.1/查看效果
- 如果啟動時就報錯,查看終端信息,解決錯誤。
如果終端沒有報錯,但是瀏覽時出現500、502等錯誤,就去項目目錄查看nginx日志和uWSGI日志,解決錯誤。 - 自己在部署時,遇到很多坑,網上的教程大多附帶virtualenv和supervisor的部署,但是連最基本的部署都說不明白,部署出來的東西性能再好也沒指導意義。基於自己踩坑脫坑的過程,寫下此文。
- 正如以上所說,我只是用單獨的一個conf文件,在nginx上部署了一個工程,沒有說明部署多個工程的問題;也沒有使用virtualenv開發環境、使用supervisor來管理進程等。請根據個人愛好和需要去實踐擴展。
原創不易,如果覺得有點用,希望可以隨手點個贊,拜謝各位老鐵!
四、作者Info
作者:南柯樹下,Goal:讓編程更有趣!
原創微信公眾號:『小鴻星空科技』,專注於算法、爬蟲,網站,游戲開發,數據分析、自然語言處理,AI等,期待你的關注,讓我們一起成長、一起Coding!
版權聲明:本文禁止抄襲、轉載 ,侵權必究!
更多獨家精彩內容 請掃碼關注個人公眾號,我們一起成長,一起Coding,讓編程更有趣!
—— —— —— —— — END —— —— —— —— ————
歡迎掃碼關注我的公眾號
小鴻星空科技