django+nginx+uwsgi項目部署

購買服務器

可以到阿里云,騰訊云,aws外國的服務器商購買服務器和域名;
其中各服務商有試用時間段,如果用于測試則可以使用免費的服務器。
大概步驟:

  1. 選擇地區;
  2. 選擇系統,一般為ubuntu16.04 x 64;
  3. 自己玩的話,最低配夠了,視具體情況而定;
    4.買完之后會讓你設置主機登錄密碼和遠程密碼;
    image.png

    購買成功之后,我們可以進入主機
    image.png

    輸入在購買時所填的遠程密碼
    image.png

    連接之后輸入主機用戶(root)和密碼(與上面遠程密碼不是同一個的,取決于你購買服務器時所填的)
    image.png

    然后升級環境
    apt update #新環境一般都更新下
  • 購買域名
    這個自己玩的可要可不要,域名要正常解析的話則國內需要備案,國外不需要


    image.png

    購買好域名備案之后,要將域名解析,綁定公網ip


    image.png

    各操作對應服務商會提供對應操作指引,按照其中執行即可。

python安裝

一般linux服務器目前都安裝python2.x版本,最新的都會裝3.x的。可以查看系統中是否安裝了python

#輸入python即可查看相關信息
python2 --version #查看python2的版本信息
pyton3 --version #查看python3的版本信息

#如需要安裝
sudo apt-get install python3.x   #安裝python

Python3和Python2是互相不兼容,但也不能卸載python2,可以將Python的指向Python3,這樣就可以默認使用python3了。

默認指向python2:
image.png

這里來改為指向python3
echo alias python=python3 >> ~/.bashrc
source ~/.bashrc   #source命令通常用于重新執行剛修改的初始化文件,使之立即生效,而不必注銷并重新登錄。

再來看下,指向python3了:
image.png

需要用2則python2即可
image.png

安裝pip3

查看pip是否安裝
image.png

如出現以上界面,表示已安裝pip了
但是需要注意是在哪個下面的,是python2還是python3下安裝的


image.png

默認是裝在python2下的
需要安裝python3的:
apt install python3-pip   #主目錄下,這可以可以全局使用pip3

注意

如果更新了pip
image.png

升級了pip,再次使用pip 安裝相關的python包的時候就出現以下錯誤再來直接使用就會報錯


image.png
ImportError: cannot import name main

解決:vim /usr/bin/pip3進去

from pip import main
if __name__ == '__main__':
    sys.exit(main())

換成下面即可:
from pip import __main__
if __name__ == '__main__':
    sys.exit(__main__._main())
image.png

安裝虛擬環境

virtualenv可以搭建虛擬且獨立的python運行環境, 使得單個項目的運行環境與其它項目獨立起來,不與其他產生沖突,即安裝在虛擬環境里的所有包,均不會對環境外的其他包產生影響,反之,在虛擬環境下運行時只能調用虛擬環境中安裝的包,不會調用外部的包。相當于局部和全局之分;

  1. virtualenv本質上是個python包, 使用pip安裝,選擇建立虛擬環境的文件夾
pip3 install virtualenv        #安裝虛擬環境     
  1. 使用virtualenv創建虛擬環境:
virtualenv  -p /usr/bin/python3 envpro    
# -p參數指定Python解釋器程序路徑,這將會使用 /usr/bin/python3 中的Python解釋器。在當前目錄下創建 envpro虛擬環境

envpro就是新建虛擬環境的目錄。envpro下擁有bin、include、lib三個文件夾。本虛擬環境所有安裝的Python庫將存放在ENV/lib/pythonX.X/site-packages/下。 創建虛擬環境就會裝好python,會將系統中的拷貝過來。

  1. 進入虛擬環境,注意:只有激活之后,才算進入該虛擬環境,否則安裝包時,依然是安裝在全局環境之下:
source envpro/bin/activate    #每次進入都要這樣做,不能直接cd 這個目錄進去

這種方式的虛擬環境配置簡單,使用也很簡單,但是需要記住虛擬環境的名字或者路徑,鑒于virtualenv不便于對虛擬環境集中管理,所以推薦直接使用virtualenvwrapper。 virtualenvwrapper提供了一系列命令使得和虛擬環境工作變得便利。它把你所有的虛擬環境都放在一個地方。

virtualenvwrapper
#1.安裝((確保virtualenv已安裝):
pip3 install virtualenvwrapper
pip3 install virtualenvwrapper-win  #Windows使用該命令
#2.創建文件目錄:
mkdir $HOME/.virtualenvs
#3.在.bashrc中(vim .bashrc)添加:
export WORKON_HOME=$HOME/.virtualenvs#virtualenvwrapper存放虛擬環境目錄
source /usr/local/bin/virtualenvwrapper.sh 
#第二行:每次登陸用戶自動執行下腳本,virtrualenvwrapper會安裝到python的bin目錄下,所以該路徑是python安裝目錄下bin/virtualenvwrapper.sh,可用whereis virtualenvwrapper.sh查看virtualenvwrapper.sh的路徑。
#4. 讀入配置文件,立即生效
source ~/.bashrc

==> 報錯:/usr/bin/python: No module named virtualenvwrapper

image.png
錯誤原因:錯誤原因:Ubuntu安裝了2.7和3.x兩個版本的python,在安裝時使用的是sudo pip3 install virtualenvwrapper在我運行的時候默認使用的是python2.x,但在python2.x中不存在對應的模塊。(virtualenvwrapper.sh文件內容如下:):
image.png

當不存在VIRTUALENVWRAPPER_PYTHON環境時,會默認選擇使用which python(我這里默認是python2)
image.png

需要增加:export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
image.png

就可以重新激活成功:
image.png

繼續完成后續配置

#5.創建虛擬環境 mkvirtualenv
#若想指定python版本,可通過"-p"指定python解釋器
mkvirtualenv -p /usr/bin/python3 blogenv
#這樣會在WORKON_HOME變量指定的目錄下新建名為blogenv的虛擬環境。
#6.使用虛擬環境
進入:workon blogenv
退出:deactivate
#7.刪除虛擬環境
rmvirtualenv blogenv
image.png
  1. 下載所需要的模塊:
PS:python項目中必須包含一個 requirements.txt 文件,用于記錄所有依賴包及其精確的版本號。其作用是用來在另一臺PC上重新構建項目所需要的運行環境依賴,以便新環境部署。
# 在以前項目環境里導出環境
pip freeze > requirements.txt    #生成requirements.txt
# 在環境里安裝相應的模塊
pip install -r requirements.txt   #安裝requirements.txt依賴,根據文件進行包安裝,可以使用xftp軟件把requitements.txt 文件放到傳到服務器上,然后指定對應路徑安裝即可;
或者
一個一個安裝項目中所需要的模塊
安裝Django    pip3 install django   
安裝相應的模塊 django-bootstrap4   django-simple-captcha 
django-ckeditor    django-pure-pagination   pymysql等等

退出虛擬環境:deactivate

安裝數據庫

  1. 安裝 Mysql : sudo apt-get install mysql-server
    下載完之后進入安裝,會提示輸入root的密碼qmpython
  2. 安裝mysql:apt install libmysqlclient-dev
  3. 安裝成功后可以通過下面的命令測試是否安裝成功:
netstat -tap | grep mysql
  1. 設置mysql允許遠程訪問,首先編輯文件/etc/mysql/mysql.conf.d/mysqld.cnf
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

注釋掉bind-address = 127.0.0.1: #允許遠程連接

保存退出(:x或者:wq)

然后進入mysql,mysql -u root -p

  1. 執行授權命令:
#創建普通用戶:
create user 'username'@'%' IDENTIFIED BY 'password';  #qmpython
#"%",表示在任何一臺電腦上都可以登錄,也可以指定某臺機器可以遠程登錄。
#給普通用戶賦權
grant all on *.* to username@'%';
#如果要授予該用戶對所有數據庫和表的相應操作權限則可用*表示, 如*.*.

flush privileges;

然后執行quit命令退出mysql服務
  1. 配置完mysql之后需要重啟mysql:
service mysql restart

Django項目部署

  • 此處從git直接clone下來方式部署
  1. 查看有沒有git git --version 沒有就安裝 apt install git;

  2. 新建存放項目的文件夾/src/www

  3. 克隆自己的項目 git clone https://github.com/xx/xxx.git

  4. 修改設置 vim project/settings.py =>ALLOWDE_HOSTS =[“服務器ip”] ;

  5. 修改數據庫對應配置;

  6. 遷移,進入項目目錄下執行

python manage.py makemigrations
python manage.py migrate
createsuperuser
  1. python manage.py runserver 0:8000
  2. 瀏覽器打開ip或:8000
    如果打開正常則Django 部署成功
    注意:還可以通過pycharm連接阿里云服務器,然后根據同步代碼功能同步過來或者XFTP同步文件過來。

uwsgi

  • WSGI
    Web Server Gateway Interface,WSGI不是服務器,python模塊,框架,API或者任何軟件,只是一種規范,描述web server如何與web application通信的規范。

  • uwsgi:與WSGI一樣是一種通信協議,是uWSGI服務器的獨占協議,用于定義傳輸信息的類型(type of information),與WSGI協議是兩種東西。

  • uWSGI:是一個web服務器,實現了WSGI協議、uwsgi協議、http協議等。

  • 安裝需要依賴的包

apt install python3-dev 
apt install gcc
  • 安裝uwsgi
pip3 install uwsgi         #在虛擬環境里面,具體看實際
  • 測試uwsgi
    在虛擬環境中創建test.py文件
    image.png
#test.py
def application(env, start_response):
        start_response('200 OK', [('Content-Type','text/html')])
        return [b"hello world"]

運行uWSGI:

uwsgi --http :8000 --wsgi-file test.py
#http :8000:使用協議http,端口8000
#wsgi-file test.py:加載指定的文件test.py

這應該直接向端口8000上的瀏覽器發送“hello world”消息。訪問:
http://www.qmpython.com:8000/ 結果:

image.png

如果要運行django項目則如下執行即可:

進入cd django項目中

uwsgi --http  :8000 --module  項目.wsgi         

瀏覽器輸入ip:port即可查看測試結果
--卸載

pip3 uninstall uwsgi
sudo apt-get remove uwsgi

Nginx

Nginx是一款自由的、開源的、高性能的HTTP服務器和反向代理服務器;同時也是一個IMAP、POP3、SMTP代理服務器;Nginx可以作為一個HTTP服務器進行網站的發布處理,另外Nginx可以作為反向代理進行負載均衡的實現。Nginx就是性能非常好的反向代理服務器,用來做負載均衡。比如靜態文件處理,安全,效率等等。

說到代理,首先我們要明確一個概念,所謂代理就是一個代表、一個渠道,我們先來了解正向代理和反向代理。

正向代理

我訪問不了某網站比如www.google.com,但是我能訪問一個代理服務器
這個代理服務器呢,它能訪問那個我不能訪問的網站,于是我先連上代理服務器,告訴它我需要那個無法訪問網站的內容,代理服務器去取回來,然后返回給我。

image.png

正向代理的過程,隱藏了真實的請求客戶端,服務端不知道真實的客戶端是誰,客戶端請求的服務都被代理服務器代替來請求。

反向代理

當我們請求 www.baidu.com 的時候,當我們訪問www.baidu.com的時候,背后可能有成千上萬臺服務器為我們服務,但具體是哪一臺,不知道,也不需要知道,只需要知道反向代理服務器是誰就好了,www.baidu.com 就是我們的反向代理服務器,反向代理服務器會幫我們把請求轉發到真實的服務器那里去。

image.png

反向代理隱藏了真實的服務端。

負載均衡

我們已經了解了代理服務器的概念,Nginx扮演了反向代理服務器的角色,那它根據什么規則進行請求分發的?不用應用場景,分發規則是否可控呢?
這里提到的客戶端發送的、Nginx反向代理服務器接收到的請求數量,就是我們說的負載量。
請求數量按照一定的規則進行分發到不同的服務器處理的規則,就是一種均衡規則。
所以~將服務器接收到的請求按照規則分發的過程,稱為負載均衡。
負載均衡在實際項目中,有硬件負載均衡和軟件負載均衡兩種,硬件負載均衡也稱為硬負載,如F5負載均衡,相對造價昂貴成本較高,但是數據的穩定性安全性等等有非常好的保障,如中國移動中國聯通這樣的公司才會選擇硬負載進行操作;更多的公司考慮到成本原因,會選擇使用軟件負載均衡,軟件負載均衡是利用現有的技術結合主機硬件實現的一種消息隊列分發機制。

使用nginx

  • 安裝nginx(在虛擬環境外執行)
apt install nginx  
  • 啟動重啟nginx
  /etc/init.d/nginx start(stop、restart)        
  • 測試nginx
nginx -t        #如果提示13: Permission denied則權限不夠,用sudo nginx -t
#如果failed,則輸入nginx -t查看錯誤信息,找到nginx.conf哪一行出錯修改即可。

在瀏覽器輸入ip地址,出現以下情況說明測試成功


image.png

PS:可以在瀏覽器中輸入公網IP:端口,端口在阿里云安全組規則里面添加安全組規則端口,nginx默認只允許80,8000(可以通過文件配置,下面會提到)

nginx + uwsgi + django

先看下從網上找的圖片


image.png

image.png

三者結合起來則需要修改幾個配置文件:

uWSGI文件配置

/src/www/文件夾下建立兩個文件qmblog_uwsgi.iniqmblog_uwsgi_params(這個.ini文件可以放在任何地方)

image.png

  • qmblog_uwsgi.ini文件
#配置域應該是uwsgi,記住這個不能丟,否則會報錯
[uwsgi]
#uwsgi監聽的socket,可以為socket文件或ip地址+端口號,用nginx的時候就配socket , 直接運行的時候配 http, http-socket = 127.0.0.1:8080
socket    = 127.0.0.1:8000

#指定項目的目錄,在app加載前切換到當前目錄
chdir           = /root/src/www/CainiaoBlog

# Django的wsgi文件,用來加載blog2/wsgi.py這個模塊
module          =  CainiaoBlog.wsgi
# Python虛擬環境的路徑
home            = /root/.virtualenvs/blogenv
# master 啟動主進程。
master   = true
# 最大數量的工作進程數
processes   = 10
# 指定工作進程中的線程數
threads = 2

# 設置socket的權限
chmod-socket    = 664
# 退出的時候是否清理環境,自動移除unix Socket 和 Pid 文件
vacuum          = true
#日志文件路徑
daemonize = /root/src/www/logback/uwsgi/blog_uwsgi.log
  • qmblog_uwsgi_params
uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;
    
uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUSET_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;
    
uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
  • 啟動
    進入qmblog_uwsgi.ini文件所在目錄執行 uwsgi --ini qmblog_uwsgi.ini 或者在其他目錄下執行要加載能訪問此配置文件的路徑如:uwsgi --ini /root/src/www/qmblog_uwsgi.ini,總而言之,記住一定要在uwsgi起作用的環境下,即在python對應虛擬環境下,且在能訪問ini文件目錄下執行;
  • 查看
  • 關閉
    sudo pkill -f uwsgi -9
nginx文件配置

/root/src/www目錄下新建nginx.conf配置文件,內容如下:

#配置文件內容:
# 轉發給哪個服務器,可以通過upstream配置項讓nginx實現負載均衡
upstream django {    
    server   127.0.0.1:8000; 
    server   127.0.1.1:8000;
}

# 設定虛擬主機配置,一個http中可以有多個server。
server {
    # 啟動的nginx進程監聽請求的端口
    listen      80;
    #定義使用域名訪問
    server_name  www.qmpython.com;  
    charset     utf-8;

    # max upload size  
    client_max_body_size 75M;    # adjust to taste

    # location 配置請求靜態文件多媒體文件。
    location /media  {
        alias  /root/src/www/CainiaoBlog/media/;  
    }
    # 靜態文件訪問的url
    location /static {
        # 指定靜態文件存放的目錄
        alias /root/src/www/CainiaoBlog/static/;
    }

#  將所有非媒體請求轉到Django服務器上
    location / {
        # 包含uwsgi的請求參數,路徑為qmblog_uwsgi_params絕對路徑
        include  /root/src/www/qmblog_uwsgi_params; 
        # 轉交請求給uwsgi
        # uwsgi_pass  127.0.0.1:8000; 
        uwsgi_pass  django;  #這個django對應開頭出的,對于動態請求,轉發到本機的端口,也就是uwsgi監聽的端口,uwsgi運行的主機和ip,后面我們會在本機的該端口上運行uwsgi進程
        # 下面兩個配置意思是如果比如通過http://www.xxx.com直接訪問的是static下的index.html或者index.htm頁面,一般用于將首頁靜態化
        #root   /root/src/www/CainiaoBlog/static/;
        #index index.html index.htm; 
    }
    #精確匹配不同于上面/,這里http://www.xxx.com會匹配這個,根據這個配置將請求轉發給另外nginx服務器,讓另外服務器提供靜態首頁。同上面的訪問index.html在另外同一臺服務器上同一配置文件中結合。
   # location = / {
    #    proxy_pass  http://ip:port;
  #  }
}

注意:上面文件引用的路徑需要能訪問加載到,可以直接在當前路徑下cd能進入相應目錄下不;
然后進入

cd /etc/nginx/sites-enabled
rm default  #刪除默認文件
ln -s /var/www/nginx.conf nginx.conf  #在此目錄下創建軟鏈接
  • 重啟 nginx
  /etc/init.d/nginx start  (restart、stop)        
image.png
  • 關閉
  /etc/init.d/nginx stop
  • 注意:django Nginx設置靜態資源,出現403 Forbidden

    如果出現靜態文件訪問資源403權限問題
    image.png

    需要查看主配置文件/etc/nginx/nginx.conf
    image.png

    這個www-data用戶不存在,默認安裝nginx給的是這個用戶,但是程序所屬的用戶不是它,www-data這個默認的用戶,沒有靜態文件的權限,所以報了個403,沒權限,需要改成對應用戶即可。


    image.png

加載/etc/nginx/nginx.conf主配置文件,然后加載前面在sites-enabled中創建的一軟鏈接指向的文件,即我們前面改的配置文件。

開機自動啟動 uwsgi 文件

which uwsgi 查看在命令在哪個路徑下的(/usr/local/bin/uwsgi)
vim /etc/rc.local
在exit 0 前加一行

/etc/init.d/nginx start   #開機自動啟動nginx
/src/www/blogenv/bin/uwsgi --ini /var/www/uwsgi.ini --chmod-socket=666 

然后reboot

靜態文件處理

1.將settings.py配置文件中DEBUG = False
說明:
1)測試環境中打開調試模式,能夠顯示詳細的報錯信息,生產環境改為False避免暴露項目內部信息;
2)生產環境下,即關閉debug后django 不會從 static 目錄讀取靜態文件,靜態文件交由nginx去處理;
2.修改ALLOWED_HOSTS =["*"], “*”表示的就是任意的ip地址,生產部署為了防范攻擊,改成本機ip地址和域名;

在pip安裝模塊的時候可能是連接的官網速度比較慢,可以使用豆瓣源
https://pypi.doubanio.com/simple/pip
如:
install xxx -i http://pypi.douban.com/simple/

本人個人博客:www.qmpython.com,就是通過以上方式搭建的。

歡迎關注微信公眾號,一起學習交流

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容