本文由雲+社區發表css
本文主要講述瞭如何一步步在生產環境上部署django和vue,操做系統默認爲centoshtml
說明:後文中出現的如下字符串均表示具體的路徑或者名稱,含義以下:前端
一個經常使用的web框架圖以下圖所示vue
框架選用.jpgpython
咱們使用nginx + uwsgi來驅動django,由於uwsgi性能很是高nginx
720333-20170312154455592-1425120615.pngweb
使用yum安裝便可redis
yum -y install nginx
啓動apache
service nginx start
此時到瀏覽器輸入對應的ip地址,出現下面頁面即表示安裝成功django
1324702136-57fb16aa00d21_articlex.png
nginx能夠新建一個配置,放在項目目錄,暫時不修改nginx的默認配置,端口號能夠換一個,而後在/etc/nginx/conf.d/內新建一個軟連接指向該配置文件,這樣nginx在讀取配置時會將該配置一塊兒讀進去。這樣,訪問端口號8080的請求便會指向咱們本身的這個配置。
server { listen 8080; server_name 132.232.50.225; root /data/; charset utf-8; access_log /data/access_narwhals.log; error_log /data/error_narwhals.log; client_max_body_size 75M; location / { uwsgi_pass 127.0.0.1:9090; include /etc/nginx/uwsgi_params; } location ^~ /admin/ { uwsgi_pass 127.0.0.1:9090; include /etc/nginx/uwsgi_params; } }
該配置中uwsgi_pass要指向uwsgi綁定的接口。(咱們先假設uwsgi配置的是9090端口)
使用yum或者pip都可安裝
yum install uwsgi # 或者 pip install uwsgi
不過這裏須要注意,若是運行uwsgi出現下面錯誤
uwsgi: option '--http' is ambiguous; possibilities: '--http-socket' '--https-socket-modifier2' '--https-socket-modifier1' '--https-socket' '--http11-socket' '--http-socket-modifier2' '--http-socket-modifier1' getopt_long() error
主要是用yum安裝的uwsgi,缺乏python的plugin,能夠安裝對應的插件
yum install uwsgi-plugin-python plugins = python (加在ini配置文件中)
uwsgi可使用命令行啓動,也可使用配置文件來啓動,推薦使用配置文件來啓動守護進程,配置文件內容以下
[uwsgi] socket = 127.0.0.1:9090 stats = 127.0.0.1:9293 workers = 4 # 項目根目錄 chdir = DJANGO_DIR touch-reload = DJANGO_DIR py-auto-reload = 1 # 在項目跟目錄和項目同名的文件夾裏面的一個文件 module= DJANGO_NAME.wsgi pidfile = /var/run/inner_manager.pid daemonize = /data/uwsgi9090.log # If you plan to receive big requests with lots of headers you can increase this value up to 64k (65535). buffer-size=65535
這裏以socket形式運行uwsgi,綁定了本地的9090端口,也就是上文nginx配置中uwsgi_pass指定的端口。
大概解釋下幾個配置的含義:
具體參數含義能夠到官方文檔查找
而後使用命令啓動uwsgi進程,其中uwsgi.ini爲上面內容的配置文件
uwsgi -i uwsgi.ini
能夠看下日誌文件有沒有報錯,或者看下ps -ef|grep uwsgi
進程有沒有跑起來。必定要確保進程正常run起來才行
至此,DJANGO已經經過nginx+uwsgi能夠訪問了
其實這裏訪問編譯好的vue靜態文件有不少方式,本文主要講述經過nginx直接訪問和經過django路由訪問
其實咱們也能夠直接經過http://ip:8080/ 來經由django的路由來訪問vue的頁面。固然要作到這樣要確保如下配置的正確
找到DJANGO_DIR根目錄下DJANGO_NAME同名文件夾下urls.py,使用通用視圖建立最簡單的模板控制器,增長一行路由
url(r'^$', TemplateView.as_view(template_name="index.html")),
這樣訪問http://ip:8080/
時會直接返回 index.html。
上一步使用了Django的模板系統,因此須要配置一下模板使Django知道從哪裏找到index.html。在project目錄的settings.py下:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [VUE_HTML_DIR], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
按照上述配置完成後,結合前面配置好的nginx和uwsgi,你已經能夠經過http://ip:8080/ 來訪問到對應的vue編譯好的VUE_HTML_DIR目錄下的index.html了,可是這時候你可能會有其餘困擾,好比找不到css樣式文件的問,這常常是靜態配置有誤致使找不到靜態文件的問題。
Django經過django.contrib.staticfiles來管理靜態文件,首先確保django.contrib.staticfiles已經添加到INSTALLED_APPS。
而後能夠在DJANGO的配置文件settings.py中增長如下幾個配置:
STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, "static") # Add for vuejs STATICFILES_DIRS = [ VUE_STATIC_DIR, # other static folders ]
STATIC_URL
對外提供WEB訪問時static的URL地址STATIC_ROOT
設置絕對路徑, 用來保存收集到的靜態文件,服務器最終也將從該路徑中獲取文件進行轉發。在collectstatic運行的時候會把STATICFILES_DIRS
中的靜態文件拷貝到這個目錄中,達到從開發環境到生產環節過程當中移植靜態文件的做用。STATICFILES_DIRS
用來配置一些開發環境下生成的靜態文件的地址,即編譯好的VUE_STATIC_DIR在url.py中添加路由
url(r'^static/(?P<path>.*)$', static.serve, {'document_root': settings.STATIC_ROOT}, name='static'),
配置好以上配置後,編譯好的靜態文件還在VUE_STATIC_DIR
目錄下,咱們最終要執行下面命令才能把STATICFILES_DIRS
中的靜態文件拷貝到STATIC_ROOT
這個目錄中,也就是最終生產環境指定的static的存放目錄
python manage.py collectstatic
那麼爲何不直接手動把構建好的VUE_STATIC_DIR中的文件拷過來呢,由於Django自帶的App:admin 也有一些靜態文件(css,js等),它會一併collect過來,畢竟nginx只認項目跟目錄的靜態文件,它不知道django把它本身的需求文件放到哪了
這樣你訪問django的admin網址http://ip:8080/admin 時,也不會出現找不到css的問題了
固然這種方式實際上是經過django的路由來訪問靜態文件的,通常的,生產環境不會經過django來轉發靜態文件,而是經過其餘服務器進行轉發,好比nginx,apache等,因此這裏咱們須要再配置下nginx的配置文件,在8080的server中增長以下路徑的配置
location /static/ { expires 30d; autoindex on; add_header Cache-Control private; alias VUE_STATIC_DIR; access_log off; }
這樣訪問靜態文件便會直接經過nginx來訪問了,不用擔憂靜態文件訪問致使Django的處理速度變慢了。
若是你想直接經過nginx訪問對應的前端vue文件,能夠從新配置一個server來訪問對應的html文件,好比上面已經使用了8080端口,咱們能夠用默認的80端口來配置個server,其中root能夠指向存放index.html文件的路徑,/static/
路徑下的root路徑能夠指向html對應的存放css和js的static文件夾,若是static就在index.html路徑下,不指認也能夠。直接修改/etc/nginx.conf便可,裏面已經有配置好的80端口的server
配置以下所示
server { listen 80 default_server; listen [::]:80 default_server; server_name _; root VUE_HTML_DIR; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } location /static/ { root VUE_STATIC_DIR; access_log off; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
這樣咱們能夠經過http://ip:80/ 來訪問vue編譯好的頁面,使用http://ip:8080/ 訪問django配置的cgi請求
上面咱們已經用到了uwsgi,後面可能還會用到redis、celery,都須要開啓守護進程,其中celery自身還不支持守護進程。那麼如何管理這麼多進程呢,這時候能夠考慮下supervisor
使用pip安裝便可
pip install supervisor
咱們能夠配置redis,celery,uwsgi進去,好比向下面同樣
[program:redis] ;指定運行目錄 directory=%(here)s/ ;執行命令(redis-server redis配置文件路徑) command=redis-server /etc/redis.conf ;啓動設置 numprocs=1 ;進程數 autostart=true ;當supervisor啓動時,程序將會自動啓動 autorestart=true ;自動重啓 ;中止信號 stopsignal=INT [program:celery.worker.default] ;指定運行目錄 directory=%(here)s/ ;運行目錄下執行命令 command=celery -A DjangoProject worker --loglevel info --logfile log/celery_worker.log -Q default -n %%h-%(program_name)s-%(process_num)02d process_name=%(process_num)02d ;啓動設置 numprocs=2 ;進程數 autostart=true ;當supervisor啓動時,程序將會自動啓動 autorestart=true ;自動重啓 ;中止信號,默認TERM ;中斷:INT (相似於Ctrl+C)(kill -INT pid),退出後會將寫文件或日誌(推薦) ;終止:TERM (kill -TERM pid) ;掛起:HUP (kill -HUP pid),注意與Ctrl+Z/kill -stop pid不一樣 ;從容中止:QUIT (kill -QUIT pid) stopsignal=INT [program:uwsgi] ;指定運行目錄 directory=%(here)s/ ;運行目錄下執行命令 command=uwsgi -i conf/uwsgi/uwsgi9090.ini ;啓動設置 numprocs=1 ;進程數 autostart=true ;當supervisor啓動時,程序將會自動啓動 autorestart=true ;自動重啓 ;中止信號,默認TERM ;中斷:INT (相似於Ctrl+C)(kill -INT pid),退出後會將寫文件或日誌(推薦) ;終止:TERM (kill -TERM pid) ;掛起:HUP (kill -HUP pid),注意與Ctrl+Z/kill -stop pid不一樣 ;從容中止:QUIT (kill -QUIT pid) stopsignal=INT
啓動supervisor輸入以下命令,使用具體的配置文件執行:
supervisord -c supervisord.conf
關閉supervisord須要經過supervisor的控制器:
supervisorctl -c supervisord.conf shutdown
重啓supervisord也是經過supervisor的控制器:
supervisorctl -c supervisord.conf reload
%(here)s 配置文件所在路徑 (program_name)s program的名字 %(process_num)02d 多進程時的進程號
注意:command中若是含有%,須要進行轉義%%
多進程時若是不指定process_name會遇到以下錯誤
Error: Format string 'celery -A INTProject worker --loglevel info --logfile log/celery_worker.log -Q diff_task,caller_task -n %h' for 'program:celery.worker.mac.command' is badly formatted: incomplete format in section 'program:celery.worker.mac' (file: 'supervisord.conf')
使用django+uwsgi+nginx,發現以下報錯
2018/10/08 14:34:33 [error] 12283#0: *8107 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 9.19.161.66, server: 132.232.50.225, request: "GET /auth/info?token=ZXlKaGJHY2lPaUprWldaaGRXeDBJaXdpZEhsd0lqb2lTbGRRSW4wOjFnOVA3aDp0bVZYcmg3XzJPR3RXSHJrbXFLRVdCZEpUdXc_ZXlKMWMyVnlibUZ0WlNJNkltVjBhR0Z1Wm1GdUlpd2lhV0YwSWpveE5UTTRPVGd3TkRjekxqZzVNekk1TVgwOjFnOVA3aDpMVXRHZkFiQkhrRTNaenFnS3NuS1RvOHBOMGM_3bdf34e6de16096f9982015a2382d3c8 HTTP/1.1", upstream: "uwsgi://127.0.0.1:9090", host: "int.oa.com", referrer: "http://int.oa.com/"
I finally found a reference to fastcgi and a 502 bad gateway error (https://support.plesk.com/hc/en-us/articles/213903705). That lead me to look for a buffer size limit in the uwsgi configuration which exists as buffer-size. The default value is 4096. From the documentation, it says: If you plan to receive big requests with lots of headers you can increase this value up to 64k (65535).
意思是uwsgi中有一項配置是buffer-size,代表收到的最大請求size,默認是4096,能夠將其改爲65535
buffer-size=65535
此文已由做者受權騰訊雲+社區發佈