nginx+uwsgi+django

@(tigerfive)[tigerfive][linux學習筆記][uwsgi][django][nginx]

前言

先決條件和目標
安裝和配置VirtualEnv和VirtualEnvWrapper
創建Django項目
設置uWSGI應用程序服務器
安裝並配置Nginx爲反向代理
結論
原文我發了另一篇文章<How To Serve Django Applications with uWSGI and Nginx on CentOS 7>

如何在CentOS 7上使用uWSGI和Nginx來運行Django應用程序

介紹

Django是一個功能強大的Web框架,可以幫助您將Python應用程序或網站變爲現實。Django包含一個簡化的開發服務器,用於在本地測試您的代碼,但對於與生產相關的任何事情,都需要更安全,更強大的Web服務器。
在本指南中,我們將演示如何在CentOS 7上安裝和配置一些組件,以支持和服務Django應用程序。我們將配置uWSGI應用程序容器服務器與我們的接口,Nginx將代理轉換爲uWSGI,使我們能夠訪問其安全性和性能特性來爲我們的應用程序提供服務。

先決條件和目標

爲了完成這個指南,你應該有一個新的CentOS 7服務器實例,配置一個非root用戶,並配置了sudo權限。您可以通過運行我們的初始服務器設置指南瞭解如何進行設置。
我們將在兩個不同的虛擬環境中安裝Django,這將允許您的項目和他們的需求分開處理。我們將創建兩個示例項目,以便我們可以在多項目環境中運行這些步驟。
一旦我們有了我們的應用程序,我們將安裝和配置uWSGI應用程序服務器。這將作爲我們應用程序的接口,它將使用HTTP將客戶端請求轉換爲我們的應用程序可以處理的Python調用。然後,我們將在uWSGI之前設置Nginx,以利用其高性能的連接處理機制和易於實現的安全功能。
我們開始吧。

安裝和配置VirtualEnv和VirtualEnvWrapper

我們將在他們自己的虛擬環境中安裝我們的Django項目來隔離每個項目的需求。爲此,我們將安裝可以創建Python虛擬環境的virtualenv,以及virtualenvwrapper,這會爲virtualenv工作流程增加一些可用性改進。
我們將使用pip(Python包管理器)來安裝這兩個組件。要獲得pip,我們首先需要啓用EPEL庫,我們可以通過鍵入以下命令輕鬆完成:

                        #sudo yum install epel-release         

一旦啓用EPEL,我們可以通過輸入以下命令來安裝pip:

                        #sudo yum install python-pip

現在你已經安裝了pip,我們可以通過輸入以下命令來全局安裝virtualenv和virtualenvwrapper:

                       #sudo pip install virtualenv virtualenvwrapper

安裝這些組件後,我們現在可以使用我們的shell來配置它所需要的與virtualenvwrapper腳本一起工作的信息。我們的虛擬環境將全部放置在我們的主文件夾Env中的一個目錄中,以便於訪問。這是通過一個名爲WORKON_HOME的環境變量來配置的。我們可以將其添加到我們的shell初始化腳本中,並可以獲取虛擬環境包裝腳本。

要將相應的行添加到您的shell初始化腳本中,您需要運行以下命令:

                         echo "export WORKON_HOME=~/Env" >> ~/.bashrc
                         echo "source /usr/bin/virtualenvwrapper.sh" >> ~/.bashrc

現在,請輸入您的shell初始化腳本,以便您可以在當前會話中使用此功能:

                         source ~/.bashrc 

你現在應該在你的home文件夾中有一個名爲Env的目錄,它將保存虛擬環境信息。

創建Django項目

現在我們有了我們的虛擬環境工具,我們將創建兩個虛擬環境,分別安裝Django,並啓動兩個項目。

創建第一個項目

我們可以通過使用virtualenvwrapper腳本提供給我們的一些命令輕鬆地創建一個虛擬環境、

通過鍵入以下內容創建您的第一個虛擬環境,其中包含您的第一個站點或項目

           mkvirtualenv firstsite

這將創建一個虛擬環境,在其中安裝Python和PIP,並激活環境。你的提示會改變你的新虛擬環境。它看起來像這樣:(firstsite)user @ hostname:〜$。圓括號中的值是你的虛擬環境的名字。 現在,通過管道安裝的任何軟件都可以安裝到虛擬環境中,而不是安裝在全局系統上。這使我們能夠在每個項目的基礎上分離我們的軟件包。

我們的第一步是安裝Django本身,因爲我們在我們的虛擬環境中安裝了這個工具,所以我們可以在沒有sudo的情況下使用pip。

          pip install django  

安裝Django後,我們可以通過鍵入以下命令創建我們的第一個示例項目:

        cd ~
        django-admin.py startproject firstsite
                                                                                <-----報錯找不到命令,find查找命令路徑,添加到環境變量。 source  一下

這將創建一個目錄名firstsite在你的家目錄。在這裏面是一個管理腳本,用於處理項目的各個方面,以及用於存儲實際項目代碼的另一個同名目錄。

進入第一級目錄,以便我們可以開始設置示例項目的最低要求。

        cd ~/firstsite

首先遷移數據庫以初始化我們的項目將使用的SQLite數據庫。如果您願意,您可以爲您的應用程序設置一個替代數據庫,但這不在本指南的範圍之內:

        ./manage.py migrate                           

現在,您的項目目錄中應該有一個名爲db.sqlite 3的數據庫文件。現在,我們可以通過鍵入以下命令創建一個管理用戶:

        ./manage.py createsuperuser                        

您將不得不選擇一個用戶名,給一個聯繫人的電子郵件地址,然後選擇並確認一個密碼。

接下來,使用文本編輯器打開項目的配置 文件:

        nano firstsite/settings.py

由於我們將設置Nginx來服務我們的網站,我們需要配置一個目錄來保存我們網站的靜態資源。這將使Nginx能夠直接提供這些服務,這將對性能產生積極影響。我們將告訴Django把它們放到我們項目的基本目錄下的靜態目錄中。將此行添加到文件的底部以配置此行爲:

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

完成後保存並關閉文件。現在,收集我們網站的靜態元素,並通過輸入以下內容將其放置在該目錄中:

           ./manage.py collectstatic

您可以鍵入“是”來確認操作並收集靜態內容。在項目目錄中將有一個名爲static的新目錄。
所有這一切,我們可以通過暫時啓動開發服務器來測試我們的項目。類型:

     ./manage.py runserver 0.0.0.0:8080

這將在端口8080上啓動開發服務器。在瀏覽器中訪問服務器的域名或IP地址,然後輸入8080。

    http://server_domain_or_IP:8080

你應該看到一個如下所示的頁面:

將/ admin添加到瀏覽器地址欄中的URL末尾,然後轉到管理員登錄頁面:

使用您通過createsuperuser命令選擇的管理登錄憑證,登錄到服務器。您將有權訪問管理接口:

經過測試該功能,通過在你的終端鍵入Ctrl-C停止開發服務器。現在我們可以繼續我們的第二個項目了。

Create the Second Project

第二個項目將以與第一個完全相同的方式創建。我們將縮短這部分的解釋,既然你已經完成了這一次。

返回到您的主目錄併爲您的新項目創建第二個虛擬環境。激活後在這個新環境中安裝Django:

                    cd ~
                    mkvirtualenv secondsite
                    pip install django        

新環境將被創建並更改爲,留下以前的虛擬環境。這個Django實例與其他配置完全分開。這使您可以獨立管理它們並根據需要進行自定義。

創建第二個項目並進入項目目錄:

                  django-admin.py startproject secondsite
                  cd ~/secondsite  

初始化數據庫並創建一個管理用戶:

                  ./manage.py migrate
                  ./manage.py createsuperuser

打開設置文件:

                   nano secondsite/settings.py 

添加靜態文件的位置,就像在以前的項目中一樣:

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

保存並關閉文件。現在,通過鍵入以下內容將靜態元素收集到該目錄中:

             ./manage.py collectstatic

最後,啓動開發服務器來測試網站:

             ./manage.py runserver 0.0.0.0:8080

您應該檢查常規網站:

              http://server_domain_or_IP:8080

還要登錄到管理網站:

             http://server_domain_or_IP:8080/admin

如果確認所有內容都按預期工作,請在終端中鍵入CTRL-C以停止開發服務器。

退出虛擬環境

由於我們現在已經完成了指南中的Django部分,所以我們可以停用我們的第二個虛擬環境:

               deactivate  

如果您需要再次在任一個Django網站上工作,你應該重新激活他們的其他環境。你可以使用workon命令來做到這一點:

            workon firstsite

Or:
workon secondsite

同樣,當您在您的網站上完成工作時停用:

            deactivate

設置uWSGI應用程序服務器

現在我們有兩個Django項目已經準備好了,我們可以配置uWSGI。uWSGI是一個應用程序服務器,可以通過名爲WSGI的標準接口與應用程序進行通信。要了解更多信息,請閱讀我們關於在Ubuntu 14.04上設置uWSGI和Nginx的指南。

Installing uWSGI

與上面鏈接的指南不同,在本教程中,我們將全面安裝uWSGI,這將減少處理多個Django項目時的摩擦。在我們安裝uWSGI之前,我們需要軟件依賴的Python開發文件,我們還需要一個編譯器。我們可以用這兩種方法來獲得
yum:

            sudo yum install python-devel gcc

現在開發文件已經可用了,我們可以通過輸入以下命令來在全局安裝uWSGI:

            sudo pip install uwsgi

我們可以通過向我們的網站傳遞信息來快速測試這個應用程序服務器,例如,我們可以通過鍵入以下命令來告訴它服務我們的第一個項目:

            uwsgi --http :8080 --home /home/user/Env/firstsite --chdir /home/user/firstsite -w firstsite.wsgi

在這裏,我們告訴uWSGI使用位於我們〜/ Env目錄下的虛擬環境來改變我們項目的目錄,並使用存儲在我們第一個第一站點目錄中的wsgi.py文件來提供文件。對於我們的演示,我們告訴它在端口8080上提供HTTP服務。如果你在瀏覽器中訪問服務器的域名或IP地址,然後是:8080,你將再次看到你的站點(/ admin界面中的靜態元素獲得“ 還沒有工作)。完成測試後,在終端中輸入CTRL-C。

Creating Configuration Files 創建配置文件

從命令行運行uWSGI對測試非常有用,但對於實際的部署並不是特別有用,我們將以“Emperor模式”運行uWSGI,它允許主進程在給定一組配置文件的情況下自動管理單獨的應用程序。

創建一個將保存您的配置文件的目錄。由於這是一個全局過程,因此我們將創建一個名爲/ etc / uwsgi / sites的目錄來存儲我們的配置文件。在創建它之後移動到目錄中:

            sudo mkdir -p /etc/uwsgi/sites
            cd /etc/uwsgi/sites

在這個目錄中,我們將放置我們的配置文件。我們需要爲每個我們正在服務的項目提供配置文件。uWSGI進程可以採用各種格式的配置文件,但由於其簡單性,我們將使用.ini文件。

爲您的第一個項目創建一個文件,並在文本編輯器中打開它:

             sudo nano firstsite.ini

在裏面,我們必須從[uwsgi]節標題開始。我們所有的信息將在這個標題下面。我們也將使用變量來使我們的配置文件更加可重用。在標題之後,使用第一個項目的名稱設置一個名爲project的變量。用擁有項目文件的普通用戶名設置另一個變量。添加一個名爲base的變量,使用您的用戶名來建立用戶主目錄的路徑:

            [uwsgi]
            project = firstsite
            username = user
            base = /home/%(username)                

接下來,我們需要配置uWSGI,以便正確處理我們的項目。我們需要通過設置chdir選項來切換到根項目目錄。我們可以通過使用%(variable_name)語法來組合主目錄和項目名稱設置。當配置被讀取時,這將被變量的值替換。

以類似的方式,我們將爲我們的項目指出虛擬環境。通過設置模塊,我們可以準確地指出如何與我們的項目進行交互(通過從項目目錄中的wsgi.py文件中導入可調用的“應用程序”)。這些項目的配置將如下所示:

            [uwsgi]
            project = firstsite
            username = user
            base = /home/%(username)

            chdir = %(base)/%(project)
            home = %(base)/Env/%(project)
            module = %(project).wsgi:application

我們想要創建一個擁有5workers的主流程,我們可以通過添加這個來實現:

            [uwsgi]
            project = firstsite
            username = user
            base = /home/%(username)

            chdir = %(base)/%(project)
            home = %(base)/Env/%(project)
            module = %(project).wsgi:application

            master = true
            processes = 5

接下來,我們需要指定uWSGI應該如何監聽連接。在我們對uWSGI的測試中,我們使用了HTTP和一個網絡端口。既然我們要使用Nginx作爲反向代理,我們有更好的選擇。

由於沒有使用網絡端口,因爲所有組件都在一臺服務器上運行,所以我們可以使用Unix套接字。這是更安全的,並提供更好的性能。這個套接字不會使用HTTP,而是使用uWSGI的uwsgi協議,這是一個爲與其他服務器通信而設計的快速二進制協議。Nginx可以使用uwsgi協議本地代理,所以這是我們最好的選擇。

我們需要設置將運行該進程的用戶。我們還將修改套接字的權限和所有權,因爲我們將給予Web服務器寫入權限。套接字本身將存儲在/ run / uwsgi目錄中(我們將創建這個目錄)uWSGI和Nginx都可以訪問它。我們將設置vacuum選項,以便在服務停止時自動清除套接字文件:

            [uwsgi]
            project = firstsite
            username = user
            base = /home/%(username)

            chdir = %(base)/%(project)
            home = %(base)/Env/%(project)
            module = %(project).wsgi:application

            master = true
            processes = 5

            uid = %(username)
            socket = /run/uwsgi/%(project).sock
            chown-socket = %(username):nginx
            chmod-socket = 660
            vacuum = true

有了這個,我們的第一個項目的uWSGI配置就完成了。保存並關閉文件。
使用變量設置文件的優點非常簡單,可重複使用。將您的第一個項目文件配置使用複製到您的第二個配置文件的基地:

            sudo cp /etc/uwsgi/sites/firstsite.ini /etc/uwsgi/sites/secondsite.ini

用你的文本編輯器打開第二個配置文件:

            sudo nano /etc/uwsgi/sites/secondsite.ini

我們只需要在這個文件中改變一個單獨的值,以使其爲我們的第二個項目工作。使用您用於第二個項目的名稱修改項目變量:

            [uwsgi]
            project = firstsite
            username = user
            base = /home/%(username)

            chdir = %(base)/%(project)
            home = %(base)/Env/%(project)
            module = %(project).wsgi:application

            master = true
            processes = 5

            uid = %(username)
            socket = /run/uwsgi/%(project).sock
            chown-socket = %(username):nginx
            chmod-socket = 660
            vacuum = true                

完成後保存並關閉文件,第二個項目應該準備好了

Create a Systemd Unit File for uWSGI 爲uWSGI創建一個Systemd單元文件

我們現在有用於服務我們的Django項目的配置文件,但是我們還沒有使這個過程自動化。接下來,我們將創建一個Systemd單元文件,以在啓動時自動啓動uWSGI。

我們將在保存用戶創建的單元文件的/ etc / systemd / system目錄中創建單元文件,我們將調用我們的文件uwsgi.service:

            sudo nano /etc/systemd/system/uwsgi.service

首先從單元部分開始,該部分用於指定元數據。我們將簡單地描述一下我們的服務:

            [Unit]
            Description=uWSGI Emperor service

接下來,我們將打開[Service]部分。我們將使用ExecStartPre指令來設置運行我們的服務器所需的部分。這將確保/ sure / uwsgi目錄被創建,並且我們的普通用戶擁有Nginx組作爲組擁有者。即使它們已經存在,帶有-p標誌的mkdir和chown命令也會成功返回。這是我們想要的。

對於由ExecStart指令指定的實際啓動命令,我們將指向uwsgi可執行文件。 我們會告訴它以“Emperor模式”運行,允許它使用它在/ etc / uwsgi / sites中找到的文件來管理多個應用程序。 我們還將添加上面所需的Systemd來正確管理進程。這些來自uWSGI文檔:

            [Unit]
            Description=uWSGI Emperor service

            [Service]
            ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi'
            ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
            Restart=always
            KillSignal=SIGQUIT
            Type=notify
            NotifyAccess=all    

現在,我們需要做的就是添加[Install]部分。 這使我們能夠指定服務應該何時自動啓動。 我們將把我們的服務與多用戶系統狀態聯繫起來。當系統設置爲多個用戶(正常操作條件),我們的服務將被激活:

            [Unit]
            Description=uWSGI Emperor service

            [Service]
            ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi'
            ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
            Restart=always
            KillSignal=SIGQUIT
            Type=notify
            NotifyAccess=all

            [Install]
            WantedBy=multi-user.target

完成後,保存並關閉文件。

此時我們將無法成功啓動服務,因爲它依賴於可用的nginx用戶。我們將不得不等待,直到安裝nginx啓動uWSGI服務。

Install and Configure Nginx as a Reverse Proxy

通過配置uWSGI並準備就緒,我們現在可以安裝和配置Nginx作爲我們的反向代理,可以使用yum來下載和安裝:

            sudo yum install nginx

一旦Nginx安裝好了,我們可以繼續編輯主配置文件:

                http {

                . . .

                include /etc/nginx/conf.d/*.conf;

                server {
                }

                server {
                }

                server {
                    listen 80 default_server;
                    server_name localhost;

                    . . .

我們創建的塊將保存我們uWSGI站點的配置。現在我們將覆蓋第一個服務器模塊所需的指令。

首先,我們需要告訴服務器端應該回應哪個端口號和域名,我們假設您的每個站點都有一個域名:

                server {
                    listen 80;
                    server_name firstsite.com www.firstsite.com;
                }

接下來,我們將告訴Nginx,我們不需要擔心失蹤的圖標。然後,我們將指定在請求這些文件時收集我們第一個網站的靜態資產的目錄。 Nginx可以直接把它們從這個目錄傳給客戶端:

                server {
                    listen 80;
                    server_name firstsite.com www.firstsite.com;

                    location = favicon.ico { access_log off; log_not_found off; }
                    location /static/ {
                        root /home/user/firstsite;
                    }
                }

接下來,我們創建一個全面的位置塊,將所有其他查詢直接傳遞給uWSGI。我們將包含/ etc / nginx / uwsgi_params文件中的uwsgi參數,並將流量傳遞給uWSGI服務器設置的套接字:

                server {
                    listen 80;
                    server_name firstsite.com www.firstsite.com;

                    location = favicon.ico { access_log off; log_not_found off; }
                    location /static/ {
                        root /home/user/firstsite;
                    }

                    location / {
                        include uwsgi_params;
                        uwsgi_pass unix:/run/uwsgi/firstsite.sock;
                    }
                }

這樣,我們的第一個服務器塊就完成了。

我們其他網站的第二個服務器塊將幾乎相同。您可以複製並粘貼我們剛創建的服務器塊來開始。您需要修改站點應該響應的域名,站點的靜態文件的位置以及站點的套接字文件:

                server {
                    listen 80;
                    server_name secondsite.com www.secondsite.com;

                    location = favicon.ico { access_log off; log_not_found off; }
                    location /static/ {
                        root /home/user/secondsite;
                    }

                    location / {
                        include uwsgi_params;
                        uwsgi_pass unix:/run/uwsgi/secondsite.sock;
                    }
                }

完成這一步後,保存並關閉文件

檢查Nginx文件的語法以確保你沒有任何錯誤:

                sudo nginx -t

如果沒有錯誤報告,我們的文件狀況良好。

我們還需要完成一項任務,才能使我們的網站正常運行。由於Nginx正在直接處理靜態文件,因此需要訪問相應的目錄。我們需要爲它的主目錄提供可執行的權限,這是它唯一缺乏的權限。

最安全的方法是將Nginx用戶添加到我們自己的用戶組中。
然後,我們可以將可執行權限添加到我們的主目錄的組所有者,給Nginx提供足夠的訪問權限來提供文件:

            sudo usermod -a -G user nginx
            chmod 710 /home/user

現在,我們可以啓動Nginx服務器和uWSGI進程:

            sudo systemctl start nginx
            sudo systemctl start uwsgi

您現在應該可以通過訪問更多的域名來訪問您的兩個項目。公共和管理界面都應按預期工作。

如果這一切順利,您可以通過輸入以下命令啓用這兩項服務:

            sudo systemctl enable nginx
            sudo systemctl enable uwsgi

Conclusion

在本指南中,我們已經建立了兩個Django項目,每個項目都在自己的虛擬環境中。我們已經將uWSGI配置爲使用爲每個項目配置的虛擬環境獨立地爲每個項目提供服務。之後,我們將Nginx設置爲反向代理來處理客戶端連接,並根據客戶端請求提供正確的項目。

Django通過提供許多常見的組件來使創建項目和應用程序變得簡單,你要專注於獨特的元素。通過利用本文中的通用工具鏈描述,您可以輕鬆地爲從單個服務器創建的應用程序提供服務。

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