Python系列之-Nginx+uWSGI+virtualenv多專案部署

門牙發表於2019-05-12

配置virtualenv及Python環境

1、新建獨立執行環境,命名為env

[root@vultr ~]# mkdir projects   # 測試的專案總目錄
[root@vultr ~]# pip3 install virtualenv
[root@vultr ~]# cd projects
[root@vultr projects]# virtualenv env --python=python3 --no-site-packages

--python:指定Python版本
--no-site-packages:不復制系統已安裝Python包
複製程式碼

2、啟用虛擬環境

[root@vultr projects]# source env/bin/activate
複製程式碼

執行後命令提示符前面會出現一個env,變成(env)[root@vultr opt]#,退出虛擬環境執行deactivate即可。

3、安裝專案依賴:pip3 install, 在虛擬環境中安裝的包,不會對系統環境造成影響。

Django專案配置

1、上傳Django專案: Hello專案

目錄結構:
Hello/
    apps/
    Hello/
    manage.py
複製程式碼

2、配置專案的資料庫資訊:vi Hello/Hello/settings.py

如果是遠端伺服器,需要修改setting.py檔案中的ALLOWED_HOSTS:
ALLOWED_HOSTS = ['*']
複製程式碼

3、資料遷移

(env)[root@vultr Hello]# python3 manage.py makemigrations
(env)[root@vultr Hello]# python3 manage.py migrate
複製程式碼

4、收集靜態檔案:vi Hello/Hello/settings.py

STATIC_ROOT = os.path.join(BASE_DIR, "static")
複製程式碼

:wq儲存後,執行

(env)[root@vultr Hello]# python3 manage.py collectstatic --noinput
複製程式碼

5、用runserver啟動專案,看是否正常執行

(env)[root@vultr Hello]# python3 manage.py runserver 0.0.0.0:8088
複製程式碼

uWSGI配置

deactivate退出虛擬環境 1、安裝uWSGI

[root@vultr Hello]# pip3 install uWSGI
複製程式碼

2、命令列執行測試
專案目錄Hello下,執行以下命令:

[root@vultr Hello]# uwsgi --http ip:埠 --home /root/env/ --file Hello/wsgi.py --static-map=/static=static

--home:指定虛擬環境的目錄
wsgi.py:Django建立專案時生成的檔案
複製程式碼

如果訪問URL正常,說明Python虛擬環境和uWSGI沒有問題.

3、使用ini配置檔案來啟動uWSGI
我習慣性建立projects目錄,目錄結構如下:

/root/projects/
            script/     --> 存放uWSGI相關的檔案,例如uwsgi.ini, uwsgi.pid...
            Hello/  --> 專案目錄
                    apps/  --> 應用程式目錄
                    Hello/  --> settings.py等檔案所在目錄
                    static/
            env/  --> 虛擬環境目錄
複製程式碼
[root@vultr projects]# vi script/uwsgi.ini

[uwsgi]
# 專案目錄
chdir=/root/projects/Hello/
# 虛擬環境目錄
home=/root/projects/env/
# 啟動uwsgi的使用者名稱和使用者組
uid=root
gid=root
# 指定專案的application
module=Hello.wsgi:application
# 指定sock的檔案路徑
socket=/root/projects/script/uwsgi.sock
# 啟用主程式
master=true
# 程式個數
workers=5
pidfile=/root/projects/script/uwsgi.pid
# 自動移除unix Socket和pid檔案當服務停止的時候
vacuum=true
# 序列化接受的內容,如果可能的話
thunder-lock=true
# 啟用執行緒
enable-threads=true
# 設定自中斷時間
harakiri=30
# 設定緩衝
post-buffering=4096
# 設定日誌目錄
daemonize=/root/projects/script/uwsgi.log
複製程式碼

4、後臺啟動停止uWSGI的命令

[root@vultr projects]# uwsgi --ini script/uwsgi.ini  # 啟動
[root@vultr projects]# uwsgi --stop script/uwsgi.pid # 停止
複製程式碼

Nginx配置

1、 配置yum:

[root@vultr projects]# vi /etc/yum.repos.d/nginx.repo

[nginx]
name=nginx repo
# 下面這行centos根據你自己的作業系統修改比如:OS/rehel
# 6是你Linux系統的版本,可以通過URL檢視路徑是否正確
baseurl=http://nginx.org/packages/centos/6/$basearch/
gpgcheck=0
enabled=1
複製程式碼

2、 安裝: yum -y install nginx

3、新增配置檔案

[root@vultr projects]# vi /etc/nginx/conf.d/Hello.conf  # 名字是隨便起的,建議跟專案目錄一樣

server {
    listen 84;  # 埠
    server_name 10.129.205.183 ;  # 域名
    access_log  /var/log/nginx/access.log  main;
    charset  utf-8;
    gzip on;
    gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream;
    
    error_page  404           /404.html;
    error_page   500 502 503 504  /50x.html;
    # 指定專案路徑uwsgi
    location / {
        include uwsgi_params; # 載入nginx和uwsgi的通訊協議模組
        uwsgi_connect_timeout 30; # 超時時間
        uwsgi_pass unix:/root/projects/script/uwsgi.sock;
    }
    # 指定靜態檔案路徑
    location /static/ {
    alias  /root/projects/Hello/static/;
    index  index.html index.htm;
    }
}
複製程式碼

4、啟動與停止Nginx

  1. 檢查uWSGI是否啟動了
[root@vultr projects]# ps -ef | grep uwsgi
root      2299     1  0 06:22 ?        00:00:00 uwsgi --ini script/uwsgi.ini
root      2301  2299  0 06:22 ?        00:00:00 uwsgi --ini script/uwsgi.ini
root      2302  2299  0 06:22 ?        00:00:00 uwsgi --ini script/uwsgi.ini
root      2303  2299  0 06:22 ?        00:00:00 uwsgi --ini script/uwsgi.ini
root      2304  2299  0 06:22 ?        00:00:00 uwsgi --ini script/uwsgi.ini
root      2305  2299  0 06:22 ?        00:00:00 uwsgi --ini script/uwsgi.ini
root      2306  2299  0 06:22 ?        00:00:00 uwsgi --ini script/uwsgi.ini
root      2361  2016  0 06:32 pts/1    00:00:00 grep uwsgi
複製程式碼
  1. 啟動Nginx
[root@vultr projects]# /etc/init.d/nginx start
複製程式碼
  1. 訪問URL,見證奇蹟的時刻到了,然後...
    Python系列之-Nginx+uWSGI+virtualenv多專案部署

ok,報錯了,莫慌。度娘查了502是伺服器錯誤,然而前面測試了Django+uWSGI沒問題,所以最有可能是在Nginx出錯了。

來,我們檢視一下Nginx的錯誤日誌檔案,日誌檔案在哪呢???

[root@vultr projects]# find / -name nginx.conf
/etc/nginx/nginx.conf
[root@vultr projects]# vi /etc/nginx/nginx.conf
複製程式碼

Python系列之-Nginx+uWSGI+virtualenv多專案部署
error_log引數就是錯誤日誌檔案了,讓我們再開啟error.log檔案,找到最後一條記錄:

2019/05/12 06:41:43 [crit] 1514#1514: *2 connect() to unix:/root/projects/script/uwsgi.sock failed (13: Permission denied) while connecting to upstream, ...(後面省略)

複製程式碼

failed (13: Permission denied) while connecting to upstream可以看出是沒有許可權???原因是我貪圖方便,直接把專案檔案以及uWSGI檔案放在了/root/目錄下!!!

好,修改路徑,先停止Nginx和uWSGI,再修改路徑/root/projects/更改為/opt/projects/:

[root@vultr projects]# uwsgi --stop script/uwsgi.pid 
[root@vultr projects]# /etc/init.d/nginx stop
停止 nginx:                                               [確定]
[root@vultr projects]# cd ..
[root@vultr ~]# mv projects /opt/
[root@vultr ~]# cd /opt/projects/
複製程式碼

然後將script/uwsgi.ini和/etc/nginx/conf.d/Hello.conf中關於路徑的都修改過來,修改好後,再次啟動uWSGI和Nginx:

[root@vultr projects]# uwsgi --ini script/uwsgi.ini 
[uWSGI] getting INI configuration from script/uwsgi.ini
[root@vultr projects]# /etc/init.d/nginx start
正在啟動 nginx:                                           [確定]
複製程式碼

再次訪問URL, 訪問正常。

多專案部署

利用virtualenv可以在伺服器上配置多個Python執行環境,因此根據Nginx、uWSGI、virtualenv可以實現一個伺服器上執行多個專案,且互不干擾。

首先我們先來了解一下Nginx+uWSGI通訊原理。

Python系列之-Nginx+uWSGI+virtualenv多專案部署

請求首先交給Nginx,如果是靜態內容Nginx就直接處理了,如果是動態內容就將請求交給uWSGI伺服器,Nginx和uWSGI之間是通過Socket來通訊的,通訊協議就是/etc/nginx/conf.d/Hello.conf裡配置的uwsgi_params檔案。

那麼,現在我們來梳理一下,Nginx是怎麼知道uWSGI在哪裡?通過什麼和uWSGI做Socket通訊,回看/etc/nginx/conf.d/Hello.conf檔案:

Python系列之-Nginx+uWSGI+virtualenv多專案部署

原來是根據uwsgi_pass指定了Nginx與uWSGI通訊的Socket檔案路徑,看到這,就知道好辦了,一個專案配置一個uwsgi.ini檔案和nginx.conf裡的一個server,那既然需要部署多個專案,那就是多個uwsgi.ini和nginx.conf裡的多個server。

好的,我們開始測試:
1、配置虛擬環境以及測試用runserver執行Django專案是否正常。 我的目錄結構是:

opt/
    projects/
        Hello/   --> 第一個Django專案
        env/     --> 第一個Django專案的虛擬環境
        World/   --> 第二個Django專案
        env_1/   --> 第二個Django專案的虛擬環境
        script/  --> uwsig.ini等檔案存放
複製程式碼

2、配置World專案的uwsgi_world.ini檔案

[root@vultr projects]# vi script/uwsgi_w.ini

[uwsgi]
# 專案目錄
chdir=/opt/projects/World/
# 虛擬環境目錄
home=/opt/projects/env_1/
# 啟動uwsgi的使用者名稱和使用者組
uid=root
gid=root
# 指定專案的application
module=World.wsgi:application
# 指定sock的檔案路徑
socket=/opt/projects/script/uwsgi_w.sock
# 啟用主程式
master=true
# 程式個數
workers=5
pidfile=/opt/projects/script/uwsgi_w.pid
# 自動移除unix Socket和pid檔案當服務停止的時候
vacuum=true
# 序列化接受的內容,如果可能的話
thunder-lock=true
# 啟用執行緒
enable-threads=true
# 設定自中斷時間
harakiri=30
# 設定緩衝
post-buffering=4096
# 設定日誌目錄
daemonize=/opt/projects/script/uwsgi_w.log
複製程式碼

3、配置Nginx

# 可以分開多個配置檔案,這裡我放在同一個配置檔案裡
[root@vultr projects]# vi /etc/nginx/conf.d/Hello.conf

server {
    listen 84;  # 埠,請注意埠
    server_name 10.129.205.183 ;  # 域名
    access_log  /var/log/nginx/access.log  main;
    charset  utf-8;
    gzip on;
    gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream;

    error_page  404           /404.html;
    error_page   500 502 503 504  /50x.html;
    # 指定專案路徑uwsgi
    location / {
        include uwsgi_params; # 載入nginx和uwsgi的通訊協議模組
        uwsgi_connect_timeout 30; # 超時時間
        uwsgi_pass unix:/opt/projects/script/uwsgi.sock;
    }
    # 指定靜態檔案路徑
    location /static/ {
    alias  /opt/projects/Hello/static/;
    index  index.html index.htm;
    }
}

server {
    listen 86;  # 埠,請注意埠
    server_name 10.129.205.183 ;  # 域名
    access_log  /var/log/nginx/access.log  main;
    charset  utf-8;
    gzip on;
    gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream;

    error_page  404           /404.html;
    error_page   500 502 503 504  /50x.html;
    # 指定專案路徑uwsgi
    location / {
        include uwsgi_params; # 載入nginx和uwsgi的通訊協議模組
        uwsgi_connect_timeout 30; # 超時時間
        uwsgi_pass unix:/opt/projects/script/uwsgi_w.sock;
    }
    # 指定靜態檔案路徑
    location /static/ {
    alias  /opt/projects/World/static/;
    index  index.html index.htm;
    }
}
複製程式碼

4、啟動uWSGI和Nginx,訪問兩個埠的URL。 ok,訪問正常。

相關文章