如何一步步在生產環境上部署django和vue

来源:https://www.cnblogs.com/qcloud1001/archive/2018/12/12/10109835.html
-Advertisement-
Play Games

本文由雲+社區發表 本文主要講述瞭如何一步步在生產環境上部署django和vue,操作系統預設為centos 說明 :後文中出現的以下字元串均表示具體的路徑或者名稱,含義如下: DJANGO_DIR 表示django的工程根目錄 DJANGO_NAME 表示django的工程名稱 VUE_HTML_ ...


本文由雲+社區發表

本文主要講述瞭如何一步步在生產環境上部署django和vue,操作系統預設為centos

說明:後文中出現的以下字元串均表示具體的路徑或者名稱,含義如下:

  • DJANGO_DIR----表示django的工程根目錄
  • DJANGO_NAME----表示django的工程名稱
  • VUE_HTML_DIR----表示vue編譯好的index.html路徑
  • VUE_STATIC_DIR----表示vue編譯好的靜態文件夾static的路徑

整體框架

一個常用的web框架圖如下圖所示

img框架選用.jpg

我們使用nginx + uwsgi來驅動django,因為uwsgi性能非常高

img720333-20170312154455592-1425120615.png

一、安裝和配置nginx

安裝

使用yum安裝即可

yum -y install nginx

啟動

service nginx start

此時到瀏覽器輸入對應的ip地址,出現下麵頁面即表示安裝成功

img1324702136-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埠)

二、安裝和配置uwsgi

安裝

使用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指定的埠。

大概解釋下幾個配置的含義:

  1. chdir----應用載入前chdir到指定目錄,一般設置為django的工程根目錄
  2. touch-reload----如果修改/碰了指定的文件,那麼重載uWSGI
  3. module----載入一個WSGI模塊的路徑,如果django的話就指向對應的wsgi文件模塊
  4. buffer-size----設置請求的最大大小 (排除request-body),這一般映射到請求頭的大小。預設情況下,它是4k。如果你接收到了一個更大的請求 (例如,帶有大cookies或者查詢字元串),那麼你也許需要增加它。它也是一個安全度量,所以調整為你的應用需要,而不是最大輸出。該值如果太小會報錯

具體參數含義可以到官方文檔查找

然後使用命令啟動uwsgi進程,其中uwsgi.ini為上面內容的配置文件

uwsgi -i uwsgi.ini

可以看下日誌文件有沒有報錯,或者看下ps -ef|grep uwsgi進程有沒有跑起來。一定要確保進程正常run起來才行

至此,DJANGO已經通過nginx+uwsgi可以訪問了

三、配置訪問vue

其實這裡訪問編譯好的vue靜態文件有很多方式,本文主要講述通過nginx直接訪問通過django路由訪問

通過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直接訪問

如果你想直接通過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請求

四、通過supervisor管理進程

上面我們已經用到了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')

中間可能遇到的坑

*8107 recv() failed (104: Connection reset by peer) while reading response header from upstream, client 錯誤

使用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

此文已由作者授權騰訊雲+社區發佈


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、window對象的屬性和方法 ①setTimeout()方法用來實現一個函數在指定毫秒之後運行,該方法返回一個值,這個值可以傳遞給clearTimeout()用於取消這個函數的執行。 ②setInterval()用來實現一個在指定毫毛數的時間里重覆調用,返回一個值,這 個值可以傳遞給clearI ...
  • 列印: 列印: 列印: break 和 continue 的區別 1.break 2.continue 練習: 對象 一、 在ECMAscript中,引用類型是一種數據結構.用於將數據和功能組織在一起.在其他語言這種數據結構一般屬於類(class)的範疇 .儘管ECMAscript是一門面向對象的語 ...
  • 先來個基礎的 需求 根據下麵需求實現如示意圖所示的郵箱輸入提示功能,註意,根據要求只需實現下麵功能 當用戶沒有任何輸入時,提示框消失 當用戶輸入字元後,顯示提示框,並且把用戶輸入的內容自動拼上郵箱尾碼進行顯示 暫時不用考慮示意圖中的紅色和藍色背景色的邏輯 註意用戶輸入中前後空格需要去除 小優化編碼 ...
  • 先放一張效果圖: 下麵是源代碼: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> div{ text-align: center; margin-top: 150 ...
  • 瀏覽器調試工具使用總結 一. console使用 console.table(),可以把對象輸出成表格的形式,直觀的觀察數據。 console.dir(),可以直觀觀察dom元素的對象形式 二. $的使用 $('selector'),獲取查詢到的第一個dom元素 $$('selector'),查找符 ...
  • 在Web頁面上,如果想模擬對話框效果,一般會給div元素添加position:fixed的樣式來實現,然後給背景添加一個半透明的遮罩。如: HTML代碼: 這種結構在大部分瀏覽器和移動設備上顯示都沒有問題,但是在蘋果手機(safari mobile)上,當底部的鍵盤或者選擇器(日期選擇,下拉列表選擇 ...
  • 最近的一個項目中的需求要對一堆元素進行排序,排序的依據是元素在頁面上面的坐標位置,然後按照順序給所有元素一個編號。如下圖所示: 排序並編號 排序並編號 做這個需求的是一個新入職的小伙,思考摸索了很久,他也沒有找到合適的方法。不得不說,部分新入職的小伙的思維能力還是有待提高啊。其實這個問題很簡單,就是 ...
  • JavaScript是運行在客戶端的腳本,因此一般是不能夠設置Session的,因為Session是運行在伺服器端的。 而cookie是運行在客戶端的,所以可以用JS來設置cookie. 假設有這樣一種情況,在某個用例流程中,由A頁面跳至B頁面,若在A頁面中採用JS用變數temp保存了某一變數的值, ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...