本文用來記錄 Django/Flask 部署的一些筆記,文中描述的系統環境為 Ubuntu,采用的服務器為 nginx 以及用 uwsgi 來連接 Django/Flask,這也是目前 Django/Flask 比較主流的部署套餐。
部署連接原理
瀏覽器發起web請求<——>nginx接收請求<——>uwsgi處理請求<—–>django程序
環境安裝
nginx
安裝 nginx(Ubuntu)
sudo apt-get install nginx
運行並查看狀態
/etc/init.d/nginx start
/etc/init.d/nginx status
Uwsgi
先安裝 python-dev,否則 uwsgi 安裝可能會報錯
apt-get install python-dev
安裝uwsgi
pip install uwsgi
安裝完后添加環境變量:
打開文件:sudo vim .bashrc,添加以下內容:
export PATH=/home/nmask/.local/bin/:$PATH
然后運行 source .bashrc 使之生效,就可以在命令行直接運行 uwsgi
或者
使用軟連接
ln -s /usr/local/python3/bin/uwsgi /usr/bin/uwsgi
環境測試
測試nginx
/etc/init.d/nginx start
測試 uwsgi 打開http://localhost:80,能看到 nginx 說明 nginx 安裝成功。
項目根目錄下創建 test.py 文件,寫入:
def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return "Hello World”
項目根目錄下運行:
uwsgi --http :8001 --wsgi-file test.py#表示運行test文件,8001端口
訪問http://localhost:8001,如果能看到 hello world,說明 uwsgi 安裝成功。
利用 uwsgi 運行 django 項目
uwsgi --http :8001 --chdir /home/nmask/mydjango --wsgi-file mydjango/wsgi.py --master --processes 4 --threads 2 --stats 127.0.0.1:8080
http : 協議類型和端口號常用選項:
- processes : 開啟的進程數量
- workers : 開啟的進程數量,等同於processes(官網的說法是spawn the specified number ofworkers / processes)
- chdir : 指定運行目錄(chdir to specified directory before apps loading)
- wsgi-file : 載入wsgi-file(load .wsgi file)
- stats : 在指定的地址上,開啟狀態服務(enable the stats server on the specified address)
- threads : 運行線程。由於GIL的存在,我覺得這個真心沒啥用。(run each worker in prethreaded mode with the specified number of threads)
- master : 允許主進程存在(enable master process)
- daemonize : 使進程在后台運行,並將日志打到指定的日志文件或者udp服務器(daemonize uWSGI)。實際上最常用的,還是把運行記錄輸出到一個本地文件上。
- pidfile : 指定pid文件的位置,記錄主進程的pid號。
- vacuum : 當服務器退出的時候自動清理環境,刪除unix socket文件和pid文件(try to remove all of the generated file/sockets)
以配置文件形式設置
myweb_uwsgi.ini
項目根目錄下創建:myweb_uwsgi.ini文件(名字可以是任意的),寫入:
# myweb_uwsgi.ini file [uwsgi] # Django-related settings socket = :8000 # socket設定的端口是uwsgi和nginx交互的端口,必須與nginx的配置文件中相同 http = :8001 # 項目所在絕對路徑 chdir = /home/nmask/mydjango # Django s wsgi file module = mydjango.wsgi # process-related settings # master master = true # maximum number of worker processes processes = 4 # ... with appropriate permissions - may be needed # chmod-socket = 664 # clear environment on exit vacuum = true
利用uwsgi運行django:(與前面命令行的方式一樣,這樣為了方便寫成了文件)
uwsgi --ini myweb_uwsgi.ini
配置文件參數:
- socket:指uwsgi運行的端口
- Chdir:運行的目錄
- Module:運行的文件
配置nginx
打開/etc/nginx/nginx.conf,http內添加以下內容:
server { listen 8890; server_name 127.0.0.1#0.0.0.0為任意IP均可訪問 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:8000; uwsgi_read_timeout 2; } location /static { expires 30d; autoindex on; add_header Cache-Control private; alias /home/fnngj/pydj/myweb/static/; } }
說明:這里的 8000 端口是 uwsgi 的端口,nginx 運行將開啟 8890 端口,也就是 nginx 的 8890 端口與 uwsgi 的 8000 端口相互通信。
部署運行
運行uwsgi
nohup uwsgi --ini myweb_uwsgi.ini &
運行nginx:
/etc/init.d/nginx start
最后訪問http://IP地址:8890,可以看到django項目已經被運行在nginx上了。
注意:在更新Django代碼后,最好重啟一下uwsgi進程,避免出現不可預知的Bug!
#關閉uwsgi和nginx sudo nginx -s stop killall -9 uwsgi
坑點
- 如果服務器是映射的,nginx配置文件里面的server_name要寫外網的IP或者域名
- 不要在python虛擬環境中使用uwsgi,會有一些問題,當然也可以解決,參考:https://stackoverflow.com/questions/14194859/importerror-no-module-named-django-core-wsgi-for-uwsgi
- 若是uwsgi運行正常,nginx運行也正常,但就是連接不起來,可以檢查下系統是否開啟了selinux,需要關閉它才行。
報錯
No module named django.core.wsgi
啟動uwsgi時報以下錯誤:ImportError: No module named django.core.wsgi for uwsgi
uwsgi在python虛擬環境中啟動時,配置文件里面要加虛擬的路徑。
打開django.init(自己創建)寫入:
home=/path/to/venv/
運行:
uwsgi --ini django.ini --protocol=http
uwsgi http is ambiguous
這也是因為虛擬環境的原因,建議退出python的虛擬環境,然后pip install uwsgi。