Django有Apache和Nginx兩種常見部署方式
主要工具:
- 一臺遠(yuǎn)程服務(wù)器
- Nginx
- uWSGI
- Django
知識點:
- 站點結(jié)構(gòu)
- Nginx結(jié)構(gòu)
- debug方式
主機使用的是DigitalOcean家的基礎(chǔ)版ubuntu,版本16.01。
從裸機開始的環(huán)境準(zhǔn)備
基礎(chǔ)環(huán)境
zsh,oh-my-zsh,vimrc從github上pull過來,一切都是熟悉的感覺。
apt-get 要更新。
Python3/pip 和 虛擬環(huán)境
主要是為了環(huán)境簡潔和適應(yīng)版本
Nginx 安裝
遠(yuǎn)程服務(wù)器這個是第一步的,沒有服務(wù)器,開發(fā)調(diào)試都是頭疼的事情。Nginx是一款反向代理服務(wù)器,可以讓網(wǎng)站的內(nèi)容呈現(xiàn)給客戶。
# install
sudo apt-get install nginx
# basic operation
sudo /etc/init.d/nginx start
sudo /etc/init.d/nginx stop
sudo /etc/init.d/nginx restart
or:
sudo service nginx start
sudo service nginx stop
sudo service nginx restart
啟動后訪問服務(wù)器ip,會看到Welcome to nginx!信息。
uWSGI 安裝
uWSGI是實現(xiàn)了WSGI的服務(wù)器。WSGI一個Web接口。提供規(guī)范化協(xié)議,提高服務(wù)器的工作效率。uWSGI本身已經(jīng)可以勝任服務(wù)器的工作,為什么要再前面擋一個Nginx,這是出于更好的安全性,更有效率的工作和Nginx作為專業(yè)的服務(wù)器的優(yōu)勢。可以詳見這個討論。
#install
apt-get install python-dev
sudo pip install uwsgi --upgrade
用wWSGI掛起一個最簡單的程序,創(chuàng)建一個文件命名test.py
# test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
#return ["Hello World"] # python2
return [b"Hello World"] # python3
用wWSGI掛起:
uwsgi --http :8000 --wsgi-file test.py
這條命令是說,使用http協(xié)議,8000端口,加載指定文件。文件很簡單,收到GET請求后,返回Hello World
,在瀏覽器輸入ip:8000
就可以看到結(jié)果了。
安裝Django
#install
pip install django
#create project
django-admin.py startproject project-name
#create app
python manage.py startapp app-name
#同步數(shù)據(jù)庫
python manage.py makemigrations
python manage.py migrate
#開發(fā)服務(wù)器
python manage.py runserver #localhost
python manage.py runserver 0.0.0.0:8000 #ip:8000端口
理解Nginx服務(wù)器的結(jié)構(gòu)
最重要的文件:一開始就要加載
默認(rèn)下,Nginx會安裝在/usr/local/nginx
,所有的配置文件在/etc/nginx
下,最主要的配置文件是 /etc/nginx/nginx.conf
,這個文件建議放在git上,或者進(jìn)行周期性備份
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.$(date "+%b_%d_%Y_%H.%M.%S")
nginx.conf
的結(jié)構(gòu)如下:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
......
}
nginx.conf
配置了主要的工作功能,include
允許從后面的地址中找到配置文件,這樣可以讓主配置文件看起來更加精簡,但是多層套用include
也不推薦,讓代碼不易讀。從默認(rèn)的配置文件可以看出,/etc/nginx/conf.d/
里所有的配置文件和/etc/nginx/sites-enalbed/
里的配置文件都會在一開始被加載。log文件在/var/log/nginx/
下。
HTTP模塊:全局配置
HTTP 模塊會處理所有來自于網(wǎng)絡(luò)的HTTP請求,這是Nginx的大門。
重點說下/etc/nginx/sites-enalbed/
這個目錄,它可以讓不同的虛擬域名分開來。一般都是通過軟連接將配置文件連接進(jìn)這個目錄,很容易修改,ngnix提供了一個配置模版:
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
Server模塊:虛擬域名的配置
在/etc/nginx/sites-enalbed/
下配置的格式:
server {
listen 80
root /usr/share/nginx/html;
server_name localhost;
location / {
}
}
server 模塊是用戶修改量最大的地方。對于每一個虛擬域名都可以有不同的配置文件。/usr/share/nginx/html
這個路徑現(xiàn)在已經(jīng)是Nginx默認(rèn)存放靜態(tài)文件的路徑了,不需要再配置。
listen: 用來監(jiān)聽端口
server_name: 自己網(wǎng)站的域名
是否可以使用不有效的域名呢?
完全可以,在局域網(wǎng)中,是一個很好的辦法。
log: log文件,HTTP模塊已經(jīng)設(shè)置過,在server模塊里可以更細(xì)致。
access_log logs/example.access.log;
access_log /srv/www/example.com/logs/access.log;
建議使用完全路徑,相對路徑是與現(xiàn)在的路徑下部分匹配的,不好控制。
location:文件系統(tǒng)配置
location
設(shè)置可以讓服務(wù)器去應(yīng)答一些要服務(wù)器資源的請求。例如:
# http://example.com/blog/
location /blog/ { }
注意字符串的匹配是最佳匹配,Nginx會選擇匹配的最好的location。更復(fù)雜的匹配情況請參照官方文件。
部署一個Nginx的最小Web結(jié)構(gòu)
實踐是檢驗真理的唯一標(biāo)準(zhǔn),這里部署一個Nginx的最小結(jié)構(gòu),看看Nginx能不能正常工作。
linux 新建用戶名用于部署Nginx并賦予權(quán)限.
visudo
# 添加權(quán)限:
username ALL=(ALL) ALL
將nginx.conf
用戶名修改為當(dāng)前用戶。
在當(dāng)前用戶的根目錄下創(chuàng)建如下結(jié)構(gòu):
mysite:
- mysite.conf
- www
- media
-test.png
- log
最簡單的目標(biāo)就是通過ip訪問網(wǎng)站里的靜態(tài)內(nèi)容。簡單的配置下,注意使用絕對路徑:
server {
listen 8000;
server_name mysite.com
charset utf_8;
access_log /home/username/mysite/log/access.log;
error_log /home/username/mysite/log/error_log;
location /media/ {
alias /home/username/mysite/media/;
}
}
# 命令行軟連接到Nginx
sudo ln -s /home/username/mysite/mysite.conf /etc/nginx/sites-enabled/
重啟Nginx后,在 http://mysite.com/media/test.png
能夠看到正常顯示內(nèi)容就說名Nginx正常工作了。log文件顯示正常。
常見的錯誤
403 forbidden
這里就要注意下用戶名了,很多時候登錄一臺主機用戶是root,而Nginx用戶不是root,所以忽略了用戶名的部署多會遇到這個問題。
- 可以將Nginx的用戶名改為root,這樣風(fēng)險會很大。
- 網(wǎng)站靜態(tài)內(nèi)容部署在當(dāng)前用戶目錄下,如列子所示。
- 在
/usr/share/nginx/html
下部署靜態(tài)文件或軟連接到網(wǎng)站目錄。
404 notfound
一般出現(xiàn)這個問題是目錄的配置出現(xiàn)問題,使用絕對路徑可解決
調(diào)試方法
最好的辦法就是log文件了,每次的請求,錯誤記錄都會非常詳細(xì)。
理解Django部署結(jié)構(gòu)
每個環(huán)節(jié)都要理解
到現(xiàn)在為止,已經(jīng)可以分別用Nginx和uWSGI掛起服務(wù)器了。說明這兩個部分都是通的:
用uWSGI掛起Django:
uwsgi --http :8000 --module mysite.wsgi
這里sWSGI會找到 mysite下的wsgi的配置文件,即mysite/wsgi.py
如果看到Django的“it worked!”信息,則說明Django被成功掛起。
通過socket連接Nginx和uWSGI
socket中文翻譯為套接字,它的作用就像一個連接器,比方說把兩段水管連接起來,每段管子都有自己不同的編號,下面就來試驗下套接字的作用。
帶socket的Nginx配置多了這個部分:
upstream django {
# server unit:///path/to/yourmysite/mysite.sock;
server 127.0.0.1:8022; #for a webport socket
}
這是要說明監(jiān)聽來自8022端口的請求,8022口做什么了呢?
uwsgi --socket :8022 --wsgi-file test.py
8022掛起了最先的python測試文件,如果有GET請求,則返回hello world。Nginx則設(shè)置為監(jiān)聽8023端口。通過socket,有檢測到8023口的外部請求,則交給8022端口去處理,這就是socket的作用,非常靈活。也說明了這一套結(jié)構(gòu)都通了:
Django sockect
upstream django {
server unit:///path/to/yourmysite/mysite.sock;
# server 127.0.0.1:8022; #for a webport socket
}
重啟Nginx,掛起uWSGI:
uwsgi --socket mysite.sock --wsgi-file test.py
在當(dāng)前項目下可以看到生成了空的文件mysite.sock,2023口測試通過。
最后拉起整個Django項目:
uwsgi --socket mysite.sock --module mysite.wsgi
看到Django工作界面,完成,Done!
常見錯誤
connect() to unix:mysite.sock failed (2: No such file or directory)
基本是路徑設(shè)置問題,upstrem和socket都要使用絕對路徑。
connect() to uunix:mysite.sock failed (13: Permission denied)
添加socket權(quán)限:
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664 # (more sensible)
參考資料:
Django Document django官方最權(quán)威的參考文檔
Setting up Django and your web server with uWSGI and nginx uWSGI提供的參考文檔,有些小問題
How To Serve Django Applications with uWSGI and Nginx on Ubuntu 16.04 DigitalOcean提供的部署指導(dǎo)
How to Configure nginx 如何配置Nginx