填坑!!!virtualenv 中 nginx + uwsgi 部署 django

一、爲什麼會有這篇文章

第一次接觸 uwsgi 和 nginx ,這個環境搭建,踩了太多坑,現在記錄下來,讓後來者少走彎路。
本來在 Ubuntu14.04 上 搭建好了環境,然後到 centos7.4 就遇到了一堆問題。下面把步驟記錄下來,中間會記錄遇到的問題及解決方案。

二、開發環境搭建

安裝 python3

我的 centos7.4 預裝了 python2.7.5 ,首先安裝 python3,這裏我選擇 python3.4。
添加epel源:

yum install epel-release

安裝Python3.4:

yum install python34

安裝 pip3

yum install python34-setuptools
easy_install-3.4 pip

安裝 django

版本選擇:
Django 1.5.x 支持 Python 2.6.5 Python 2.7, Python 3.2 和 3.3
Django 1.6.x 支持 Python 2.6.X, 2.7.X, 3.2.X 和 3.3.X
Django 1.7.x 支持 Python 2.7, 3.2, 3.3, 和 3.4 (注意:Python 2.6 不支持了)
Django 1.8.x 支持 Python 2.7, 3.2, 3.3, 3.4 和 3.5. (長期支持版本 LTS)
Django 1.9.x 支持 Python 2.7, 3.4 和 3.5. 不支持 3.3 了
Django 1.10.x 支持 Python 2.7, 3.4 和 3.5
Django 1.11.x 支持 Python 2.7, 3.4, 3.5 和 3.6(長期支持版本 LTS) 最後一個支持 Python 2.7 的版本
Django 2.0.x 支持 Python 3.4, 3.5 和 3.6 (注意,不再支持 Python 2)

安裝 django 1.11.13 :

pip3 install Django==1.11.13

驗證 django 是否安裝成功,終端上輸入 python3 ,點擊 Enter,進入 python3 環境:

>>> import django
>>> django.VERSION
(1, 11, 13, 'final', 0)
>>> django.get_version()
'1.11.13'

安裝 Virtualenv (虛擬環境依賴)

1. 爲什麼要安裝虛擬環境依賴

在開發Python應用程序的時候,我係統安裝的 Python3 只有一個版本:3.4。所有第三方的包都會被pip3 安裝到 Python3 的 site-packages 目錄下。如果我們要同時開發多個應用程序,那這些應用程序都會共用一個Python3 ,就是安裝在系統的Python 3。如果應用A應用需要 django1.11,而應用B需要 django 2.0 怎麼辦?
這種情況下,每個應用可能需要各自擁有一套“獨立”的Python運行環境。virtualenv 就是用來爲一個應用創建一套“隔離”的Python運行環境。
virtualenv 用的時候參數比較複雜,本文不細說了,可以上網搜索瞭解一下,這裏在再安裝 virtualenvwrapper ,顧名思義,virtualenvwrapper 就是對 virtualenv 的一個包裝,讓其用起來更簡單。

2. pip安裝虛擬環境依賴

pip3 install virtualenv
pip3 install virtualenvwrapper

3.配置環境變量

修改 ~/.bashrc 配置環境變量:
centos7.4 中:

if [ -f /usr/bin/virtualenvwrapper.sh ]; then
  export WORKON_HOME=$HOME/virtualenvs
  export PROJECT_HOME=$HOME/workspace
  export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
  source /usr/bin/virtualenvwrapper.sh
fi

ubuntu 14.04中:

if [ -f /usr/local/bin/virtualenvwrapper.sh ]; then
  export WORKON_HOME=$HOME/.virtualenvs
  export PROJECT_HOME=$HOME/workspace
  export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
  source /usr/local/bin/virtualenvwrapper.sh
fi

修改後使之立即生效(也可以重啓終端使之生效):

source ~/.bashrc

這是第一個坑:在 Ubuntu 14.04 中,virtualenvwrapper.sh 文件路徑和 centos7.4 中不一樣在,這個坑很容易發現,因爲下面,你執行命令的時候會報錯,找不到文件,這個坑容易填。

3. 虛擬環境使用方法:

mkvirtualenv env1:創建運行環境 env1
workon env1: 工作在 env1 環境 或 從其它環境切換到 env1 環境
deactivate: 退出終端環境
其它的:
rmvirtualenv ENV:刪除運行環境ENV
mkproject mic:創建mic項目和運行環境mic
mktmpenv:創建臨時運行環境
lsvirtualenv: 列出可用的運行環境
lssitepackages: 列出當前環境安裝了的包

創建的環境是獨立的,互不干擾,無需sudo權限即可使用 pip 來進行包的管理。

三、部署環境搭建

安裝 nginx

1.安裝 nginx

ubuntu 中:

apt-get install nginx

centos中:

yum install epel-release
yum install nginx

2.驗證 nginx 是否安裝成功

查看 nginx 配置文件:

cat /etc/nginx/nginx.conf

截取部分內容如下:

截圖第二行,配置了 nginx 錯誤日誌保存地址,

重點關注 http 下的 server 中 listen 顯示了默認監聽的端口是 80 ,可以修改端口號。
server 上面有一行: include /etc/nginx/conf.d/*.conf;,這樣我們可以將自定義的配置文件,放到 /etc/nginx/conf.d/ 目錄下,以 .conf 後綴命名即可。

驗證 nginx 是否安裝成功,則啓動 nginx :

service start nginx

通過瀏覽器訪問 該 ip 80 端口,能正確返回下面頁面,說明 nginx 安裝成功。

坑:網上收到很多資料啓動 nginx 的命令:nginx start,nginx -s start,nginx -s reload。可能是 nginx 版本不同原因,本人親測,啓動、關閉、重新加載 nginx 服務命令如下:

service start nginx
service stop nginx
service restart nginx

** 追加:**
systemctl start nginx

安裝 uwsgi

1.安裝 uwsgi

python 安裝 uwsgi 方法有很多,但是也有坑。官方文檔上說:
要構建uWSGI,您需要Python和一個C編譯器(gcc並且clang受支持)。根據您希望支持的語言,您將需要他們的開發頭文件。在Debian / Ubuntu系統上,您可以安裝它們(以及構建軟件所需的其他基礎架構),具體如下:

首先安裝依賴文件:
Ubuntu 中:

apt-get install build-essential
apt-get install python-dev

centos中:

yum install epel-release
yum groupinstall "Development Tools"
yum install python-devel

坑:上面的命令針對 python2,對應 python3 中,Ubuntu 中應該改成是 apt-get install python3-dev,而 centos 中,yum install python3-devel 會找不到 python3-devel 包,網上有人說執行 yum install -y python3-devel.x86_64,同樣也找不到包。同時應注意, ubuntu 和 centos 中包名也不一樣。解決方法:
How to install python3-devel on red hat 7

所以針對 python3:
ubuntu 中:

apt-get install python3-dev

centos 中:
先執行:yum search python3 | grep devel,

python34-cairo-devel.x86_64 : Libraries and headers for python34-cairo
python34-greenlet-devel.x86_64 : C development headers for python34-greenlet
python34-devel.x86_64 : Libraries and header files needed for Python 3
                      : development
python34-gobject-devel.x86_64 : Development files for embedding Python 3.4
python36-devel.x86_64 : Libraries and header files needed for Python development
shiboken-python34-devel.x86_64 : Development files for shiboken

然後依次執行:

yum install -y python34-cairo-devel.x86_64
yum install -y python34-greenlet-devel.x86_64
yum install -y python34-devel.x86_64
yum install -y python34-gobject-devel.x86_64
yum install -y shiboken-python34-devel.x86_64

我把 python3.4 相關的包都安裝了。

  • 下載源碼編譯:
wget https://projects.unbit.it/downloads/uwsgi-latest.tar.gz
tar zxvf uwsgi-latest.tar.gz
cd <dir>
make

坑:上面步驟也是對應於 python2, 對於 python3 在 make 之前,一定要先執行:
python3 uwsgiconfig.py --build ,執行這個命令可能會報錯:

原因是 python-devel 對應的 python3 依賴包沒有安裝。如果不巧,你剛好沒有執行這個命令,就直接編譯,並且通過了,則相當於,到時候,會出現 uwsgi 執行時找不到 module 或者 app ,
諸如 "No module named site " 或者下面信息之類的錯誤。

cannot open shared object file: No such file or directory
unable to load app 0
  • pip3 安裝(推薦)
    pip3 install uwsgi
    如果出現錯誤,則是依賴包沒安裝好,見上面下載源碼編譯的坑。

2.驗證 uwsgi 是否安裝成功

下面的來自 uwsgi 官方文檔:

我們從一個簡單的“Hello World”例子開始:

def application (env , start_response ):
    start_response ('200 OK' , [('Content-Type' ,'text / html' )])
    return  [ b “Hello World” ]

(保存爲foobar.py)。
如您所見,它由一個Python函數組成。它被稱爲“應用程序”,因爲這是uWSGI Python加載程序將搜索的默認函數(但您明顯可以自定義它)。
部署HTTP端口9090上
現在啓動uWSGI運行一個HTTP服務器/路由器,將請求傳遞給你的WSGI應用程序:

uwsgi --http:9090 --wsgi-file foobar.py

就這樣。

下面通過瀏覽器訪問 該 ip 80 端口,能正確返回“ Hello World”。
注意:如果前面沒有成功安裝 python3 相關的依賴包,這裏也能正確訪問。但是部署 django 網站時會出錯。

如果出現下面錯誤:

your processes number limit is 16384
your memory page size is 4096 bytes
detected max file descriptor number: 65536
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
probably another instance of uWSGI is running on the same address (:8080).
bind(): Address already in use [core/socket.c line 769]

則是 uwsgi 啓動太多次了,可以用命令殺掉這個端口在重啓:

sudo fuser -k 8080/tcp
(用自己配置的端口號)

四、virtualenv + nginx + uwsgi 部署 django 網站

如果前面的步驟都沒問題了,這一步只要把配置文件寫正確,就沒什麼問題了。記得在虛擬環境中安裝所有的 project 需要依賴包。
下面是一個簡單示例:

uwgsi 配置

uwsgi 支持多種形式的配置,可以執行 uwsgin 直接帶參數,可以用 xml 文件配置等等,這裏用 ini 文件配置。
新建一個 ini 文件,比如命名爲:'dj_uwsgi.ini'

[uwsgi]
socket = :9090
chdir = /home/sharpcj/PythonProjects/testsite     # 切換到 project 目錄
env = DJANGO_SETTINGS_MODULE=testsite.settings    
module = testsite.wsgi
master = true
wsgi-file = testsite/wsgi.py
home = /home/sharpcj/.virtualenvs/testsite_evn   # python 及相關依賴包所在 path

touch-file = testsite/wsgi.py

processes = 4
threads = 2

chmod-socket = 664
vacuum = true

注意:爲了配合 nginx 工作,端口協議是 socket , 如果換成 http ,則可以直接運行uwsgi,就能通過瀏覽器訪問頁面了。命令爲 uwsgi dj_uwsgi.ini

nginx 配置

在 /etc/nginx/conf.d/ 下創建 testsite.conf 文件:

server {
    listen         9999; 
    server_name    127.0.0.1 
    charset UTF-8;
    access_log      /var/log/nginx/myweb_access.log;
    error_log       /var/log/nginx/myweb_error.log;

    client_max_body_size 75M;

    location /media  {
        alias /home/sharpcj/PythonProjects/testsite/media;
    }
 
    location /static {
        alias /home/sharpcj/PythonProjects/testsite/static;
    }
 
    location / {
        uwsgi_pass  127.0.0.1:9090;
        include     /etc/nginx/uwsgi_params;
    }
 }

listen 指定的是nginx代理uwsgi對外的端口號。

server_name 網上大多資料都是設置的一個網址(例,www.example.com),我這裏如果設置成網址無法訪問,所以,指定的到了本機默認ip。在進行配置的時候,我有個問題一直想不通。nginx到底是如何uwsgi產生關聯。現在看來大概最主要的就是這兩行配置。

    include uwsgi_params;

    uwsgi_pass 127.0.0.1:9090;

include 必須指定爲 uwsgi_params ;而 uwsgi_pass 指的本機IP的端口號與 dj_uwsgi.ini 配置中的文件中的必須一致。

此時啓動 nginx 服務,並啓動 uwsgi 服務,即可通過 ip:9999 訪問網站。
通過這個IP和端口號的指向,請求應該是先到nginx的。如果你在頁面上執行一些請求,就會看到,這些請求最終會轉到uwsgi來處理。

ps: 這個過程本應不算複雜,前天花了一下午時間沒搞定,昨天又花了一下午時間才搞定。網上搜到的文章比較亂,有些太簡單的看不懂,有些又太囉嗦的不知道核心的幾步是什麼,有些又因爲版本不對,或者環境不同,不能成功,希望本文能幫到後面的人。

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