Centos7 + Python3.7 + Django2/3 + Nginx1.6.1 + uwsgi2.0.18 配置

谷明科技,專注於大數據和人工智能領域的創新者

本文主要是針對 Django 項目的生產部署操作

網絡客戶端 <-> 網站服務器(nginx) <-> the socket <-> uwsgi <-> Django

這裏,uwsgi 是與 Django 交互的一種 python 標準,而 nginx 和 uwsgi 之間的交互方式是以 socket 包的方式進行的

前提:

  • 已經安裝了 python 3.7 版本
  • 已經安裝了 django 版本可以在 django 2.0 - 3.0
  • 已經有一個可以正常運行的 django 項目,我們這裏假設我們用的 django 教程裏的項目 mysite. 
  • 已經安裝了 Nginx1.6.1, 沒有安裝的可以翻看之前的教程。

說明下,我們下面會頻繁提到幾個名詞,提前備註下

  • 系統環境: 以 root 用戶進入的系統環境
  • 虛擬環境:是用 virtualenv 搭建並已經激活的環境
  • 項目目錄虛擬環境中有 manage.py 的目錄,是絕對路徑
  • IP: 你的服務器的訪問 ip,如果是雲服務器的話,就是外網 ip

1. 在虛擬環境中安裝 uwsgi 

注意,這裏強烈推薦用 pip 安裝,否則後續會遇到一些問題。

pip install uwsgi
which uwsgi

看下路徑是不是指向虛擬環境的

2. 在虛擬環境中測試並配置 uwsgi

測試:

項目目錄下,新建一個 test.py 文件。

# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2

uwsgi --http :8000 --wsgi-file test.py

這裏的 8000 端口應該是可用而且空閒的,所謂可用是指 阿里雲 或者 騰訊雲 的該端口安全組是已經配置了的,具體不懂的可以百度,所謂空閒的,是指該端口沒有被佔用,具體查詢方法爲如下:

netstat -nltp | grep 8000

打開 http://IP:8000 是否能看到 “hello world” 的輸出,如果是,說明如下通信鏈路是通的

客戶端 <-> uWSGI <-> Python

如果不能看到,再看下上面的內容,是不是遺忘了一些步驟或者配置有問題

3. 虛擬環境中測試 django 項目的 uwsgi 通信

首先,看下你的 django 項目是不是可以跑通

python manage.py runserver 0.0.0.0:8000

然後打開 http://IP:8000/admin 是否可以看到你的 django 登錄界面,如果可以的話,說明項目沒問題。

然後輸入

uwsgi --http :8000 --module mysite.wsgi

這裏的 mysite 是 django 項目的名字,如果你的項目名字是其他的,這裏對應修改一下,我們本篇都會以 mysite 作爲默認的項目名

然後打開 http://IP:8000/admin 是否可以看到你的 django 登錄界面,如果可以的話,說明如下的網絡通信沒有問題

客戶端 <-> uWSGI <-> Django

4. 系統環境中測試 nginx

這裏我們默認 nginx 已經安裝完成而且安裝方式是 yum 安裝

打開 http://IP:80 是否可以看到 nginx 的歡迎界面,如果可以說明以下通信鏈路是沒問題

客戶端 <-> nginx 服務器

如果有問題,可以看下 /var/log/nginx/error.log 日誌,如果是端口被佔用,直接停掉對應的進程然後重新啓動 nginx

nginx -s reload

打開 nginx 路徑,如果不知道可以打 nginx -t 或者 whereis nginx 

我這邊的 nginx 的路徑是 /etc/nginx,裏面的文件架構是

nginx
-- conf.d
   fastcgi_params
   nginx.conf
   uwsgi_params
   ...

這裏的 conf.d 就是 nginx 配置文件的目錄,下一步我們會用到。

同時,因爲我們需要在項目中使用到 uwsgi_params 文件,所以把這個文件複製到項目目錄中,並且文件的擁有者是開發者而不是 root。

5. 虛擬環境中配置 nginx

在項目目錄下,新建一個 mysite_nginx.conf 文件,並填入以下信息

# mysite_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
    # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
    server 127.0.0.1:8001; # socket 的網絡端口
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name IP; # 服務器IP
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # 可以自己調整

    # Django media
    location /media  {
        alias 項目目錄/media;  # 媒體文件路徑
    }

    location /static {
        alias 項目目錄/static; # 靜態文件路徑
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     項目目錄/uwsgi_params; # 項目的 uwsgi_params 文件
    }
}

然後做一個指向該配置文件的軟鏈接

ln -s 項目目錄/mysite_nginx.conf /etc/nginx/conf.d/

6. 虛擬環境中部署靜態文件

首先,修改一下 django 項目的配置文件(項目目錄/setting.py

將其中的 debug = True 改爲 debug = False

然後在文件末尾添加如下一行

STATIC_ROOT = os.path.join(BASE_DIR, "static/")
STATIC_URL = '/static/'

同時需要對 mysite 文件夾下面的 urls.py 文件做一個簡單的修改

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

同時,需要對訪問的ip和域名地址做一個設置,否則會造成 connection refused 這樣的問題,這裏我的例子是這樣:

ALLOWED_HOSTS = ['127.0.0.1', '外網IP','www.guming-tech.com']

然後在你的項目目錄中添加2個子目錄

/media/
/static/ 

分別存放媒體文件和靜態文件,然後輸入以下命令

python manage.py collectstatic

然後放一張圖片在 media 目錄下,什麼圖片都可以,我們這裏假設圖片爲 show.png

接下來,切入到系統環境中,然後重啓 nginx

nginx -s reload

然後訪問 http://IP:8000/media/show.png, 如果圖片能夠顯示,則說明 nginx 的項目配置是沒有問題的

7. 虛擬環境中測試 nginx,uwgsi 和 python 之間的 socket 端口通信

輸入以下命令

uwsgi --socket :8001 --wsgi-file test.py

這裏的 8001 端口是基於第5步中對 nginx 項目配置文件的配置,忘記的可以重新翻看下

然後打開 http://IP:8000 是否可以看到 “hello world”,如果可以的話,說明如下的通信鏈路是沒有問題的

客戶端 <-> nginx 服務器 <-> the socket <-> uWSGI <-> Python

8. 虛擬環境中測試 nginx,uwgsi 和 python 之間的 unix socket 通信

上一步我們使用了TCP的 socket 的端口通信,這個是比較簡單的,但是在實際的網站中,更好的解決方案是 unix socket 方法,具體設置方法如下:

編輯 mysite_nginx.conf 對文件的頭部部分做一些修改

server unix://項目目錄/mysite.sock; # socket 文件,自動生成
# server 127.0.0.1:8001; # for a web port socket (we'll use this first)

切換到系統環境中,重啓 nginx

然後輸入

uwsgi --socket mysite.sock --wsgi-file test.py

然後打開 http://IP:8000 應該可以看到 “hello world”,如果有 permission error 的話,試下如下2種方法

uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664

我這邊是對第一種方法有效

9. 虛擬環境中測試 nginx,uwgsi 和 django 項目之間的完整通信

這次試下如下的命令

uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=666

然後打開  http://IP:8000/admin 是不是可以看到 django 的登錄界面了

10. 虛擬環境中使用 ini 配置文件

在項目目錄下新建一個 mysite_uwsgi.ini 文件,並放入以下內容

# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = 項目目錄
# Django's wsgi file
module          = mysite.wsgi
# the virtualenv (full path),這個是你使用 virtualenv 建立的項目的絕對路徑,但不是項目路徑,一般是項目目錄的上層路徑
home            = 項目目錄的上層路徑

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = 項目路徑/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 666
# clear environment on exit
vacuum          = false

然後輸入

uwsgi --ini mysite_uwsgi.ini

然後打開  http://IP:8000/admin 應該還是可以通信

11. 系統環境下安裝 uwsgi

依然是用 pip 安裝 uwsgi

pip install uwsgi

然後在系統環境中進入到項目目錄,輸入

uwsgi --ini mysite_uwsgi.ini

然後打開  http://IP:8000/admin 應該還是可以通信

12. Emperor 模式下的配置

uwsgi 可以在 “Emperor” 皇帝模式下工作,即可以監視所有的 uwsgi 配置文件

mkdir /etc/uwsgi
mkdir /etc/uwsgi/vassals
ln -s 項目目錄/mysite_uwsgi.ini /etc/uwsgi/vassals/
uwsgi --emperor /etc/uwsgi/vassals --uid user --gid user-group

具體的 user 和 user-group 這裏你可以自己選擇,比方說對系統用戶 django

groups django

輸出 django 的用戶組,填進去試試

13. 設置 uwsgi 系統自啓動

這裏我們選擇推薦的 /etc/rc.local 進行編輯

然後加入如下的命令

uwsgi安裝路徑/uwsgi --emperor /etc/uwsgi/vassals --uid 用戶 --gid 用戶組 --daemonize /var/log/uwsgi-emperor.log

這裏的 uwsgi安裝路徑可以通過以下的命令得到

which uwsgi

然後

source /etc/rc.local

需要提到的一點 /etc/rc.local 在centos7的版本里是隻讀的,所以我們需要給它加入一個可執行的權限,同時 /etc/rc.local 的服務名爲 rc-local,所以我們這裏將其設定爲自啓動

chmod +x /etc/rc.d/rc.local
systemctl enable rc-local

可以嘗試重啓下系統,看看服務是否自動打開

systemctl status rc-local

直接打開 http://IP:8000/admin 應該可以看到網站正常運行

部署完成

14. 項目的修改和重新加載

如果在項目中新增加了一個應用app,需要對項目進行重啓,這時候我們需要對 uwsgi 的配置文件 mysite_uwsgi.ini 做一個修改。即添加一行

touch-reload = 項目路徑/reload.ini

然後在項目目錄中,輸入以下命令

touch reload.ini

這時候不只要重新啓動 nginx 還有 uwsgi(已經在rc-local中)

nginx -s reload
killall uwsgi
source /etc/rc.local

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章