本文主要介紹如何在Linux平臺上部署Django相關項目,關於Django項目的部署在互聯網論壇上有不少的資料,筆者在查閱衆多資料並通過實踐後發現結果並不如意(或多或少老是遇到一些問題,每每與資料的預期不相符)。在瀏覽了許多資料後筆者整理得出了部署Django項目的通常性方法,部署的方法有不少種,在此筆者選擇了較爲經常使用的基於uwsgi和Nginx的部署方案。python
部署前主要是須要作一些與服務器相關的準備工做,本次教程的服務器採用了阿里雲的 CentOS 7.3 64位,固然做爲資料學習你們也可以使用Linux虛擬機進行部署。另外,爲了方便的Linux的使用和部署操做,在此推薦你們安裝XSHELL(https://www.netsarang.com/en/xshell/)和XFTP(https://www.netsarang.com/en/xftp/),XSHELL主要是用於鏈接服務器並進行終端操做,而XFTP則可用來進行服務器與開發主機的文件傳輸(好比windows和linux間的傳輸)。mysql
在此還須要注意的是,若是你們和我同樣使用阿里雲服務器,那麼在部署前還須要留意一下設置相應的網絡安全組,這個安全組主要是用於設置外網對服務器端口的訪問權限,因爲阿里雲服務器中有的端口默認未開啓被訪問,因此爲了可以讓外網訪問到部署的項目(好比Django網站),那麼就須要開啓相應的端口(好比80端口)。安全組設置可在阿里雲控制檯(https://ecs.console.aliyun.com/)的服務器實例中查看到,以下左邊功能欄的【本實例安全組】,點擊進入後可在安全組列表中查看到相關規則設置,點擊【配置規則】後即可進行端口訪問權限的設置(好比下圖中新設置的80和8000端口)。linux
本篇採用uwsgi和nginx的部署方案,所以在Linux環境下咱們須要預先安裝好如下軟件,不過在此只作簡單的描述,讀者們有一個概念性的印象即可(若是想要深刻理解可自行學習相關資料),各個軟件具體的安裝方法和使用操做將在後文一一講述。nginx
總的來講,以上幾個模塊在Django項目中的關係可表述爲下圖:web
以上爲部署項目最基本的軟件需求,具體的軟件環境還須要結合實際狀況進行配置(好比一些項目可能須要mysql、memcache和redis等環境,那麼還須要進行相關環境的搭建)redis
本次部署工做分爲兩個環節——開發主機和服務器主機,開發主機主要負責項目的開發與調試,確保項目質檢合格後方可在服務器主機中進行部署與運維操做。sql
在此以全新的Django 3.0項目爲例進行闡述,並預先建立好了一個測試用的testapp,其主要是用於展現一個測試網站首頁,總體項目架構以下圖所示:shell
開啓DEBUG,在終端輸入以下命令開啓項目,並在瀏覽器訪問127.0.0.1:8000,觀察項目是否正常運行數據庫
$ python manage.py runserver 0.0.0.0:8000
關閉DEBUG,並在settings,py中設置ALLOWED_HOSTS和STATIC_ROOT兩個常量django
在此,筆者爲方便DEBUG的切換,將兩種模式下的設置進行了以下整合:
# SECURITY WARNING: don't run with debug turned on in production! DEBUG = True if DEBUG == True: # 開發模式下容許全部域名訪問 ALLOWED_HOSTS = ['*'] else: # 發行模式下容許訪問的域名地址 ALLOWED_HOSTS = ['XXX.XXX.XXX.XXX'] # …… # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.0/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) if DEBUG == False: # 發行模式下設置靜態文件收集目錄,收集靜態文件以便後續 Nginx 的配置 STATIC_ROOT = os.path.join(BASE_DIR, 'static_dist')
以後運行命令打包項目的虛擬環境依賴,命令完成後在項目根目錄下可見到新生成的requirements.txt文件,這裏面記錄着本項目所依賴的pip包,以便後續在服務器中的安裝。
$ pip freeze > requirements.txt
# requirements.txt
asgiref==3.2.3
Django==3.0.3
pytz==2019.3
sqlparse==0.3.0
將項目源文件(不含venv虛擬環境文件夾)經過XFTP傳輸到服務器中(好比本教程將其遷移至服務器下的’/srv/Django_projects/DjangoDistTest/’目錄下)
至此,開發主機的工做已所有完成.
Linux下Python3環境的安裝在此不進行闡述,這裏主要講解virtualenv的安裝與使用,同時爲方便後文的講述,假設咱們的python3安裝目錄爲‘/usr/local/python3’。
virtualenv是python的一個虛擬環境管理工具,經過它能夠很方便地建立一個python虛擬環境(這裏稍微補充一下,虛擬環境是指拷貝式地建立一個與系統python版本如出一轍的python運行環境,但這個環境不包含任何多餘的依賴包,咱們能夠在這個虛擬環境中根據項目針對性地安裝一些依賴包,從而方便python項目的管理並減小包的冗餘)。
$ pip3 install virtualenv
上文已經說明,軟連接是爲了將一程序配置爲命令以方便Linux直接在終端經過命令行進行操做
$ ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv
直接在咱們的項目目錄下執行相關命令,其中參數’python’指向所拷貝的源python程序
$ cd /srv/django_projects/DjangoDistTest
$ virtualenv --python=/usr/local/python3/bin/python3 venv
開啓虛擬環境,同時檢查所安裝的包
$ source ./venv/bin/activate
$ (venv) pip list
安裝項目依賴包,以後再次查看包若發現已裝上所有依賴則表示虛擬環境已搭建好
$ pip3 install -r requirements.txt
執行’python manage.py makemigrations’和’python manage.py migrate’進行數據庫遷移(若是以前將.sqlite3文件拷貝過來了,那麼遷移時可能會不一樣,刪除.sqlite3文件便可;另外,對於不一樣版本的Linux,這一步可能會出現sqlite3文件錯誤,緣由是系統未安裝sqlite3,所以查閱相關資料安裝sqlite3便可)
$ (venv) python manage.py makemigrations
$ (venv) python manage.py migrate
因爲咱們項目如今的DEBUG爲關閉狀態,考慮到上文中的STATIC_ROOT設置,因此須要收集靜態文件資源(關於靜態資源路由的設置請參看文末附錄)
$ (venv) python manage.py collectstatic
以後運再次運行項目,在瀏覽器中訪問網址便可(服務器公網IP:8000或域名:8000)。另外,這裏還須要留意一下阿里雲安全組是否已經設置好。
因爲uwsgi是基於python編寫的,所以咱們能夠直接經過pip進行安裝(筆者以前在查閱資料時發現有的博主是經過CentOS 的yum進行安裝的,不過經實踐後操做效果不是那麼好,所以仍是推薦使用pip進行安裝)。這裏須要注意的是,uwsgi因爲是經過系統進程來調用,因此要在系統級別中安裝,所以咱們須要預先退出虛擬環境再進行安裝。
$ (venv) deactivate
$ pip3 install uwsgi
$ ln -s /usr/local/python3/bin/uwsgi /usr/bin/uwsgi
直接使用uwsgi命令行形式開啓項目,參數http表示端口號,module表示項目的wsgi文件,home表示所使用的虛擬環境目錄
$ uwsgi --http :8000 --module DjangoDistTest.wsgi --home=/srv/django_projects/DjangoDistTest/venv/
以後使用瀏覽器進行訪問便可
上面這種經過命令行的方法已經能夠啓動項目,但若是每次啓動項目都輸入一長串命令的話會比較費力,所以下面介紹經過ini文件配置的方式啓動項目
在項目根目錄下新建ini文件(好比本例中的DjangoDistTest_uwsgi.ini),並輸入如下配置信息,以後即可經過運行命令’uwsgi –ini DjangoDistTest_uwsgi.ini’來啓動該項目了
# DjangoDistTest_uwsgi.ini
[uwsgi] # Django相關的設置 # 項目根目錄 chdir = /srv/django_projects/DjangoDistTest # Django的wsgi文件 module = DjangoDistTest.wsgi # 虛擬環境路徑 home = /srv/django_projects/DjangoDistTest/venv/ # 指定端口 http = :8000 # Django 和 uwsgi的相關日誌記錄位置,注意要預先在項目中新建log文件夾 daemonize = /srv/django_projects/DjangoDistTest/log/uwsgi.log # 進程相關的設置 # 主進程 master = true # 最大數量的工做進程 processes = 10 # socket文件路徑,用於與 Nginx 進行通訊 socket = /srv/django_projects/DjangoDistTest/DjangoDistTest.sock # 設置socket文件的權限 chmod-socket = 666 # 退出時是否清理環境 vacuum = true
$ uwsgi –-ini DjangoDistTest_uwsgi.ini
Nginx服務能夠直接經過yum命令進行安裝
$ yum install nginx’
安裝完成之後,使用命令’systemctl start nginx’便可開啓nginx服務,以後使用瀏覽器訪問服務器公網ip(即http 80端口),若出現以下界面則表示nginx已成功啓動(有的系統可能會出現」Welcome to NGINX!」的歡迎界面,這兩種都是能夠的,主要與系統版本和配置有關)
$ systemctl start nginx
固然,也能夠經過命令’systemctl status nginx’查看nginx服務的狀態
$ systemctl status nginx
此外,還有相對應的restart和stop命令控制重啓和中止,後續感興趣的同窗也能夠把Nginx服務設置成開機自動啓動。(這裏再補充一下下,對於之前版本的CentOS,須要將命令改寫成對應的」service nginx XXX」格式)
在完成好uwsgi和Nginx的安裝後,咱們即可經過Nginx配置將兩者進行關聯,即當外網訪問某一端口(好比80端口)時Nginx會自動轉發至相應的uwsgi服務器進行處理。這一關聯的映射文件存放在’/etc/nginx/conf.d’目錄下(新安裝的Nginx可能沒有該文件夾,須要本身手動建立一下),所以,咱們在該目錄下新建相關映射文件DjangoDistTest.conf。(注意下面的server_name填上公網ip或域名)
# DjangoDistTest.conf
upstream DjangoDistTest { # 設置 socket 通訊文件位置 server unix:///srv/django_projects/DjangoDistTest/DjangoDistTest.sock; } server { # 監聽的端口號 listen 80; # 域名 server_name XXX.XXX.XXX.XXX; #若是有域名的話,就寫上域名,好比"unikfox.cn wwwunikfox.cn XXX.XXX.XXX.XXX" charset utf-8; # 最大的文件上傳尺寸 client_max_body_size 75M; # 轉發非靜態文件請求到Django服務器 location / { uwsgi_pass DjangoDistTest; # uwsgi_params文件地址 include /etc/nginx/uwsgi_params; } # 轉發靜態文件 http 請求 location /static { alias /srv/django_projects/DjangoDistTest/static_dist; } }
以後從新啓動uwsgi和Nginx服務便可,因爲上述配置中監聽了80端口,所以如今咱們只須要經過在瀏覽器訪問服務器公網ip或域名便可訪問Django項目了(而不須要再填寫8000端口)
上文已經提到,uwsgi是一個進程,它有可能由於某些神祕力量而被迫終止,一旦uwsgi進程退出了那麼它所對應的Django項目也就中止了,所以爲了不uwsgi的結束風險,咱們可使用supervisor工具進行進程管理,以使當uwsgi異常退出時能自行恢復。
使用pip3在系統級中進行安裝
$ pip3 install supervisor
$ ln -s /usr/local/python3/bin/supervisord /usr/bin/supervisord
$ ln -s /usr/local/python3/bin/supervisorctl /usr/bin/supervisorctl
接下來,在項目根目錄下進行相關的文件配置便可(如本例中的」DjangoDistTest_supervisor.conf」)
# DjangoDistTest_supervisor.conf # supervisor程序名字 [program:DjangoDistTest] # supervisor執行命令 command = uwsgi --ini DjangoDistTest_uwsgi.ini # 項目的目錄 directory = /srv/django_projects/DjangoDistTest # 開始的時候等待多少秒 startsecs = 0 # 中止的時候等待多時秒 stopwaitsecs = 0 # 自動開始 autostart = true # 程序掛了後自動重啓 autorestart = true # 輸出的log文件 stdout_logfile = /srv/django_projects/DjangoDistTest/log/supervisord.log # 輸出的錯誤文件 stderr_logfile = /srv/django_projects/DjangoDistTest/log/supervisord.err [supervisord] # log的級別 loglevel = info # 設置supervisorctl管理員配置 [supervisorctl] # supervisorctl登陸的的地址和端口號,端口號可自定義 serverurl = http://127.0.0.1:XXXX # supervisorctl的用戶名和密碼 username = unikfox password = 123456 [inet_http_server] # supervisor的服務器,與上面serverurl的端口號一致 port = :XXXX # 用戶名和密碼 username = unikfox password = 123456 [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
以後即可在項目根目錄下使用命令啓動supervisor進程
$ supervisord -c DjangoDistTest_supervisor.conf
對於進入管理控制檯,可以使用以下的命令
$ supervisorctl -c DjangoDistTest_supervisor.conf
經常使用的管理命令:
使用'help'可查看supervisorctl所支持的全部命令
固然,除此之外,也還能夠經過瀏覽器訪問配置文件中serverurl的方式管理進程
如此一來,Django項目的部署便大功告成啦~完結撒花"o((>ω< ))o"
這裏還須要注意一點的是,重啓centOS後如需部署則需手動開啓如下兩個服務:
固然,你們也能夠嘗試把這兩個設置成開機自動啓動,這樣就不再用每次開機都手動輸入命令啦。
# DjangoDistTest/urls.py
from django.contrib import admin from django.urls import path,include # 處理網站圖標 from django.views.generic.base import RedirectView # 處理靜態文件的訪問 from django.views import static from django.conf import settings from django.conf.urls import url urlpatterns = [ path('admin/', admin.site.urls), path('', include('testapp.urls')), url(r'^favicon.ico$', RedirectView.as_view(url=r'static/images/icon.ico')), #網站圖標 ] + [ url(r'^static/(?P<path>.*)$', static.serve, {'document_root': settings.STATIC_ROOT}, name='static') #靜態資源,只適用於DEBUG爲False的狀況 ]
以上即是本次的《CentOS 7 下Django項目部署(基於uwsgi和Nginx)》,Django項目的部署方式不止本案例一種,有關更多的部署方式你們能夠查閱相關網絡資料,重要的是,只要適合本身的方式那它就是好的方式。
關於本教程,如各位讀者有一些疑問、想法或是更好的看法,歡迎留言交流與分享。