項目環(huán)境:python2.7, django1.9涯鲁, ubuntu(阿里云服務器)
1.利用scp將項目傳上阿里云服務器溪椎,運行開發(fā)服務器測試
(下面的項目名我都用projectname表示)運行命令:
????????cd?projectname # 進入項目projectname目錄
????????python manage.py runserver 0.0.0.0:8000
(運行開發(fā)服務器測試,確保開發(fā)服務器能正常打開網(wǎng)站)
這里有一個簡易的辦法讓項目一直在后臺運行:nohup罩抗,進入項目目錄下運行命令:
????????nuhup python manage.py runserver 0.0.0.0:8000&
在當前目錄下會生成一個nohup.out文件炮姨,項目的輸出信息全在里面,錯誤信息可從里面查找栖袋。但這不叫部署,下面開始部署抚太。
2. 安裝nginx 和需要的包
2.1 安裝 nginx 等軟件
????????ubuntu / Linux Mint 等塘幅,下面簡寫為 (ubuntu):
????????sudoapt-get?install python-dev?nginx
2.2 安裝 supervisor, 一個專門用來管理進程的工具,我們用它來管理 uwsgi 進程
????????sudopip?install supervisor
在這有一個問題需要注意一下的就是尿贫,如果你是centOS用戶电媳,不是則直接進入3,請先查看一下你的seLinux是否開啟庆亡,因為其存在安全性問題匾乓,會導致后面你利用nginx做反向代理你的項目時訪問被拒絕。運行命令又谋,將 SELinux 設置為寬容模式拼缝,方便調(diào)試:
????????sudo?setenforce?0
防火墻相關的設置:
可以選擇臨時關閉防火墻
????????sudo service?iptables?stop
或者開放一些需要的端口,比如?8002
????????sudo iptables?-A?INPUT?-p?tcp?-m?tcp?--dport?8002 -j?ACCEPT
上面的兩條命令彰亥,如果是 CentOS用戶用
臨時關閉防火墻
????????sudo systemctl?stop?firewalld
或者?開放需要的端口
????????sudo firewall-cmd?--zone=public?--add-port=80/tcp--permanent
????????sudo firewall-cmd?--reload
3.使用uwsgi來部署
安裝uwsgi
? ? ? ? sudo pip install uwsgi --upgrade
使用uwsgi 運行項目(我的項目放在/root下)
? ? ? ? uwsgi --http :8002 --chidir /root/projectname --home=/path/to/venv --module project.wsgi
這樣就可以跑了珍促,--home 指定virtualenv 路徑,如果沒有可以去掉剩愧。project.wsgi 指的是 project/wsgi.py 文件.
如果想安裝virtualenv可以按下面步驟安裝,不想則略過直接到4:
為什么要安裝virtualenv娇斩?答案來自”廖雪峰python“(在開發(fā)Python應用程序的時候仁卷,系統(tǒng)安裝的Python3只有一個版本:3.4。所有第三方的包都會被pip安裝到Python3的site-packages目錄下犬第。如果我們要同時開發(fā)多個應用程序锦积,那這些應用程序都會共用一個Python,就是安裝在系統(tǒng)的Python 3歉嗓。如果應用A需要jinja 2.7丰介,而應用B需要jinja 2.6怎么辦?這種情況下,每個應用可能需要各自擁有一套“獨立”的Python運行環(huán)境哮幢。virtualenv就是用來為一個應用創(chuàng)建一套“隔離”的Python運行環(huán)境带膀。)
下面開始安裝:
? ? ? ? pip install virtualenv
然后,假定我們要開發(fā)一個新的項目橙垢,需要一套獨立的Python運行環(huán)境垛叨,可以這么做:
第一步,創(chuàng)建目錄:
????????mkdir myproject
? ? ? ? cd myproject
第二步柜某,創(chuàng)建一個獨立的Python運行環(huán)境嗽元,命名為venv:
? ??????virtualenv --no-site-packages venv
命令virtualenv就可以創(chuàng)建一個獨立的Python運行環(huán)境,我們還加上了參數(shù)--no-site-packages喂击,這樣剂癌,已經(jīng)安裝到系統(tǒng)Python環(huán)境中的所有第三方包都不會復制過來,這樣翰绊,我們就得到了一個不帶任何第三方包的“干凈”的Python運行環(huán)境佩谷。
建的Python環(huán)境被放到當前目錄下的venv目錄。有了venv這個Python環(huán)境辞做,可以用source進入該環(huán)境:
? ? ? ? source venv/bin/activate
注意到命令提示符變了琳要,有個(venv)前綴,表示當前環(huán)境是一個名為venv的Python環(huán)境秤茅。下面你就可以正常安裝各種你想要的第三方包稚补,運行python命令
在venv環(huán)境下,用pip安裝的包都被安裝到venv這個環(huán)境下框喳,系統(tǒng)Python環(huán)境不受任何影響课幕。也就是說,venv環(huán)境是專門針對myproject這個應用創(chuàng)建的五垮。
退出當前的venv環(huán)境乍惊,使用deactivate命令:
? ??????deactivate
此時就回到了正常的環(huán)境,現(xiàn)在pip或python均是在系統(tǒng)Python環(huán)境下執(zhí)行放仗。
3.1 查詢端口
如果在3中出現(xiàn)端口被占的情況润绎,通過命令查詢端口:
? ? ? ? lsof -i:8002
再利用查詢到的pid,通過kill命令關掉相關程序:
? ? ? ? kill -9 pid
或者按程序名稱查詢:以下兩個命令都一樣的效果诞挨,只是顯示略有區(qū)別:
? ? ? ? ps -ef | grep uwsgi
? ? ? ? ps aux | grep uwsgi
4.使用supervisor來管理進程
安裝 supervisor 軟件包
? ??????(sudo)?pip?install?supervisor
生成 supervisor 默認配置文件莉撇,比如我們放在 /etc/supervisord.conf 路徑中:
????????(sudo)?echo_supervisord_conf?>?/etc/supervisord.conf? ??????
打開 supervisord.conf 在最底部添加(每一行前面不要有空格,防止報錯):
????????[program:projectname]? ??????
????????command=/path/to/uwsgi?--http?:8002 --chdir?/path/to/projectname?--module?projectname.wsgi
????????directory=/path/to/projectname
????????startsecs=0
????????stopwaitsecs=0
????????autostart=true
????????autorestart=true
command 中寫上對應的命令惶傻,這樣棍郎,就可以用 supervisor 來管理了。
啟動 supervisor:
????????(sudo)?supervisord?-c?/etc/supervisord.conf? ??????
重啟 projectname 程序(項目):
? ??????(sudo)?supervisorctl?-c?/etc/supervisord.conf?restart?projectname
啟動银室,停止涂佃,或重啟 supervisor 管理的某個程序 或 所有程序:
? ??????(sudo)?supervisorctl?-c?/etc/supervisord.conf?[start|stop|restart]?[program-name|all]
以 uwsgi 為例励翼,上面這樣使用一行命令太長了,我們使用 ini 配置文件來搞定辜荠,比如項目在 /root/projectname 這個位置汽抚,
在其中新建一個 uwsgi.ini 全路徑為 /root/projectname/uwsgi.ini
????????[uwsgi]? ??????
????????socket?=?/root/projectname/projectname.sock
????????chdir?=/root/projectname
????????wsgi-file=?projectname/wsgi.py
????????touch-reload?=??/root/projectname/reload
????????processes?=?2
????????threads?= 4
????????chmod-socket?=?666
????????chown-socket?=www-data:www-data
????????vacuum?=?true
在這有幾個要注意的問題:
? ? ? ? (1)./root/projectname/projectname.sock ,待會配置nginx時我們把它和nginx關聯(lián)起來侨拦,在這我們采用的sock方式通信殊橙,也可以直接采用ip地址加端口的形式,比如socket=127.0.0.1:8003狱从,則后面配置nginx的時候也要寫成一樣的就行膨蛮。
? ? ? ? (2).chmod-socket?=?666 ,chown-socket?=www-data:www-data有些人在后面可能會出現(xiàn)權限問題季研,所以在這直接設好敞葛,還有chown-socket設置,也就是gid与涡,uid設置
? ? ? ? (3).不建議把 sock 文件放在 /tmp 下惹谐,比如 /tmp/xxx.sock (不建議)!有些系統(tǒng)的臨時文件是 namespaced 的驼卖,進程只能看到自己的臨時文件氨肌,導致 nginx 找不到 uwsgi 的 socket 文件,訪問時顯示502酌畜,nginx 的 access log 中顯示 unix: /tmp/xxx.sock failed (2: No such file or directory)怎囚,所以部署的時候建議用其它目錄來放 socket 文件,比如放在運行nginx用戶目錄中桥胞,也可以專門弄一個目錄來存放 sock 文件恳守,比如 /tmp2/
? ??????sudomkdir-p?/tmp2/&&?sudochmod777?/tmp2/
然后可以用?/tmp2/projectname.sock?這樣的路徑了。
修改 supervisor 配置文件中的 command 一行:
? ??????[program:projectname]
????????command=/path/to/uwsgi?--ini?/root/projectname/uwsgi.ini
????????directory=/root/projectname(我的項目是放在/root下贩虾,你們按照你們的即可)
????????startsecs=0????
5.配置 Nginx
在nginx下新建一個自己的項目projectname
????????sudo?vim?/etc/nginx/sites-available/projectname.conf
寫入以下內(nèi)容:
????????server?{
????????????listen??????8002;
????????????server_name?localhost;? ? ? ? ?#有域名寫域名催烘,沒域名寫localhost或者" _" 或者公網(wǎng)ip
????????????charset?????utf-8;
????????????client_max_body_size?75M;
????????????location?/media??{
????????????????alias?/path/to/project/media;
????????????}
????????????location?/static?{
????????????????alias?/path/to/project/static;
????????????}
????????????location?/?{
????????????????uwsgi_pass??unix:///root/peojectname/projectname.sock;
????????????????include?????/etc/nginx/uwsgi_params;
????????????}
????????}
激活項目:
????????sudo?ln?-s?/etc/nginx/sites-available/projectname.conf?/etc/nginx/sites-enabled/projectname.conf
測試配置語法問題:
? ??????sudo?service?nginx?configtest
如果顯示fail,則通過下面命令查看具體原因:
? ? ? ? sudo nginx -t
重啟 nginx 服務器:
????????sudo?service?nginx?reload?或?sudo?service?nginx?restart?或?/path/to/nginx?-s?reload? ?
如果啟動成功缎罢,則說明目前配置沒有問題伊群,如果啟動失敗,則應該是nginx配置沒配好策精。
6.總結:
我在配置的時候出現(xiàn)的很多問題現(xiàn)總結如下:
?(1)nginx配置之后測試成功舰始,但啟動失敗,當時配置的時候我發(fā)現(xiàn)是/etc/nginx/nginx.conf 文件被我不知道怎么給修改了蛮寂,導致出現(xiàn)server not allow here.是因為nginx讀取了/etc/nginx/sites-available/projectname.conf里面的配置,而這里面又沒有http易茬。projectname.conf這個文件應該是include在/etc/nginx/nginx.conf 文件里面的酬蹋,修改回來之后則nginx啟動成功及老。
(2)nginx啟動成功了,但是沒有成功代理項目范抓,我用superivsorctl啟動項目之后發(fā)現(xiàn)可以直接通過8002端口訪問項目骄恶,nginx監(jiān)聽8002端口啟動失敗,查看原因發(fā)現(xiàn)地址被占匕垫,停止supervisorctl之后8002端口被放出僧鲁,我在/etc/supervisord.conf和uwsgi.ini中均未指定端口,原因可能是superivsorctl在啟動時啟動了我其他時候配置過的項目或者運行了我之前利用uwsgi測試項目的命令象泵,導致端口被占用寞秃。此時我考慮換一個端口8003,啟動成功,但訪問頁面時失敗偶惠。
分析是uwsgi.ini配置了端口還是superivsorctl配置了端口春寿,我先單獨運行uwsgi --ini uwsgi.ini 發(fā)現(xiàn)成功運行且未占用端口,顯然是因為運行superivsorctl占用了端口忽孽。
(3)基于此考慮暫時放棄supervisor绑改, 考慮先利用uwsgi --ini uwsgi.ini 命令在前臺運行,端口未被占兄一,nginx監(jiān)聽8002端口厘线,啟動成功,訪問頁面出現(xiàn)502,查看錯誤日志/var/log/nginx/error.log,發(fā)現(xiàn)是(13,permission deny)出革,
a.查看網(wǎng)上資料發(fā)現(xiàn)很多人因為用的是centOS系統(tǒng)造壮,出現(xiàn)seLinux安全性問題,一般解決方案關掉就行蹋盆,上面我已經(jīng)寫了费薄,
b.第二種情況是說權限問題,將chmod-socket?=?666 栖雾,chown-socket?=www-data:www-data設置成這個楞抡,這里有一個問題就是,因為我是采用sock通信析藕,啟動uwsgi自動生成.sock文件召廷,雖然我修改了權限,你會發(fā)現(xiàn)生成的sock文件權限并沒有變化账胧,這時你應該刪除現(xiàn)在的sock文件竞慢,重新啟動uwsgi,然后在啟動nginx治泥,看看你們有沒有解決問題筹煮,
c.但我仍然沒有解決問題,最后原因發(fā)現(xiàn)了是因為我用root身份運行的uwsgi居夹,在/etc/nginx/nginx.conf里面的用戶卻是www-data,將其改成root之后败潦,成功訪問本冲。
(4)之前我用uwsgi在前臺通過設置http端口命令運行項目的時候發(fā)現(xiàn)static靜態(tài)資源文件加載不出來,那是因為uwsgi沒有理會靜態(tài)資源文件劫扒,通過nginx反向代理之后檬洞,靜態(tài)資源文件成功加載。
(5)還有一個問題沒有解決就是沟饥,我的uwsgi是在前臺運行的添怔,supervisor又會出現(xiàn)莫名奇妙的8002端口占用,查看uwsgi進行發(fā)現(xiàn)有很多個進程在運行贤旷,這里考慮使用nohup 將uwsgi在后臺運行广料,命令:
? ? ? ? nohup uwsgi --ini uwsgi.ini&
重啟nginx:
? ? ? ? sudo service nginx restart
成功實現(xiàn)代理。
后期繼續(xù)研究這個supervisor占用我8002端口的問題遮晚,從性能上利用supervisor管理uwsgi肯定比nohup更好性昭。