django+uwsgi+nginx 前后端分離部署配置


本文僅用於記錄自己的踩坑過程,避免以后有同樣需求的時候沒思路

開發環境

后端部分

  • django==3.2.8
  • sqlite3==3.36.0

前端部分

  • vue==2.6.14
  • elementui (版本不知道)
  • axios (版本不知道)

服務器環境

  • uwsgi==2.0.20
  • nginx==1.20.1

所有的代碼文件都位於 /myweb 目錄下,該目錄的結構如下:

這里的/myweb/backend/daily_exercise/exercise文件夾是使用 djangoadmin startproject 時自動創建的,/myweb/backend/daily_exercise/daily目錄則是使用 python manage.py startapp 命令創建的

后端部分位於/myweb/backend/daily_exercise,前端部分位於/myweb/frontend/daily_exercise

后端使用 uwsgi 進行部署,加上 nginx 進行轉發以避免跨站問題,前端只用 nginx 部署。

后端部署:uwsgi 部署 django

先安裝 uwsgi

pip install uwsgi

然后在任意地方創建一個 uwsgi 的配置文件。本例中叫 uwsgi.ini,位於 /myweb/backend/ 目錄下,雖然 /myweb/backend/daily_exercise/ 目錄下還有一個同名的 uwsgi.ini,但是在服務器端部署用不到這個文件,這個文件是在本地部署時候用到的,因為在服務器上的 /myweb/backend/daily_exercise/ 目錄被我設置成了 git 的遠程倉庫,所以在本地提交的時候也把這個配置文件提交上來了。
/myweb/backend/uwsgi.ini文件內容如下

[uwsgi]
http=:8000
master=True
processes=4
threads=4
chdir=/myweb/backend/daily_exercise
wsgi-file=/myweb/backend/daily_exercise/exercise/wsgi.py
vacuum=True
max-requests=5000
daemonize=/var/log/uwsgi/daily_exercise.log
pidfile=/tmp/daily_exercise.pid
py-autoreload=1

其中,要注意的是以下幾個參數:

  • http 表示程序將要運行在哪個端口。本例是 8000
  • chdir 是 django 項目的根目錄地址,也就是 manage.py 文件所在的目錄
  • wsgi-file 是項目中 wsgi.py 文件地址。這里可以寫成是相對地址,也可以是絕對地址
  • daemonize 指明 django 項目運行時產生的日志文件位置
  • pidfile 指定 django 項目運行時將要產生的進程文件名稱和位置
  • py-autoreload 指定是否自動重載。如果等於 1,則在代碼更新后,uwsgi 服務會自動重載。否則需要手動重載(命令是:uwsgi --reload /tmp/daily_exercise.pid)

然后執行:

uwsgi uwsgi.ini

即可部署完畢。可以查看 /var/log/uwsgi/daily_exercise.log 的內容,檢查是否有報錯,如果沒有報錯就沒問題。同時也可以直接打開 http://服務器id:8000 (或其它在 django 中定義的有效路徑)來觀察部署結果。

前端部署:nginx 部署純前端項目

如果系統中沒有安裝 nginx,需要先安裝,網上有很多教程。

安裝完后,修改 /etc/nginx/nginx.conf 配置文件

http {
  server {
    localhost /frontend/daily {
      alias /myweb/frontend/daily_exercise;
    }
  }
}

如上,在默認的 http > server 內加入以下三行即可。

    localhost /frontend/daily {
      alias /myweb/frontend/daily_exercise;
    }

其中 localhost 后面的 /frontend/daily 是自定義的訪問地址,訪問時在服務器地址后面加上這個自定義地址即可,如:http://服務器IP/frontend/daily

至此,前端、后端分別部署完畢。但是由於 django 部署使用的是 8000 端口,前端部署使用的是默認的 80 端口,前端發請求時會有跨站(CROS)問題。

比如,前端需要向后端接口 http://localhost:8000/daily/api 發請求獲取數據,則在前端會出現跨站請求的錯誤。

一個解決的思路是,前端只向默認的 80 端口發請求,由 nginx 轉發到 8000 端口,就不會有這個問題。

配置 nginx 解決跨站問題

同樣簡單,在前述的 nginx 配置文件 /etc/nginx/nginx.conf 文件中加上轉發的規則,同樣是在 http -> server 下添加:

locahost /daily/api {
  proxy_pass http://127.0.0.1:8000/daily/api;
  proxy_redirect default;
}

這樣,當在瀏覽器中打開 http://服務器IP/daily/api 時,nginx 會轉發至 http://127.0.0.1:8000/daily/api 這個地址。

當然以上是硬編碼的方式,並不是最優解,網上還有其它方式可以更加靈活地實現這種不同端口之間的轉發。

別忘了修改 django 項目中的跨站訪問配置

需要安裝 django 的 cros 插件:

pip install django-cros-headers

修改 /myweb/backend/daily_exercise/exercise/settings.py 文件,添加以下內容

CORS_ORIGIN_WHITELIST = (
    'http://127.0.0.1:8000',
    'http://localhost:8000',
    'http://localhost',
    'http://127.0.0.1',
)

CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'POST',
    'PUT',
)

CORS_ALLOW_HEADERS = (
    'XMLHttpRequest',
    'X_FILENAME',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'Pragma',
)

再修改同文件下的MIDDLEWARE變量,增加corsheaders.middleware.CorsMiddleware

允許跨站(CROS問題解決)后,在前端代碼中可以使用相對路徑來訪問后端的接口(這樣可以在沒有配置 nginx 轉發的本地環境中也能正常運行),例如:

解決 sqlite3 版本過低的問題

在本地(或服務器)使用 python manage.py runserver 時,如果 sqlite3 版本過低,項目是運行不起來的,會 sqlite3 版本過低的錯誤,因為 django3 要求 sqlite3 的版本要大於等於 3.9.0,可以先按網上的教程升級系統的 sqlite3

sqlite 官網中提供的最新版本應該是遠高於 3.9 的。
升級完后,使用 python manage.py runserver 命令執行應該沒問題了,但是使用 uwsgi 部署時,很可能依然還會報版本過低的錯誤,如下,可在uwsgi.ini文件內指定的/var/log/uwsgi/daily_exercise.log文件中看到錯誤:

估計是程序找不到最新安裝的 sqlite3,原因不明,也未找到解決辦法,按網上說的添加參數到 bash_profile 無效,使用參數重新編譯 python 也沒有作用。

最終我是直接修改 django 中的判斷語句來避開這個檢測的。如上圖中的黃色框部分,修改這個文件里面的check_sqlite_version函數,如下:

上圖是修改后的,修改前黃框中應該是(3, 9, 0)

至此,問題解決,部署完畢!


解決管理后台靜態文件丟失的問題

首先,需要配置一些變量,在settings文件末尾中添加:

配置url.py如下

最后執行 python manage.py collectstatic 操作,將相關靜態文件都 copy 到 static_root 的路徑下(實際是copy了admin的static文件到指定的 static 文件夾內)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM