簡體   English   中英

使用gunicorn和nginx部署Django

[英]Deploying Django with gunicorn and nginx

這是一個廣泛的問題,但我想得到一個規范的答案。 我一直在嘗試在Django中使用gunicornnginx部署一個站點。 在閱讀了大量的教程后,我已經取得了成功,但我無法確定我所遵循的步驟是否足以運行一個沒有問題的站點,或者可能有更好的方法來實現它。 這種不確定性很煩人。

這就是為什么我正在為新手尋找一個非常詳細且解釋清楚的答案。 我不想過多地解釋我所知道的和我不知道的事情,因為這可能會使答案有所偏差,而其他人可能會從你的答案中獲益較少。 但是,我想提到的一些事情是:

  • 您認為哪種“設置”最佳? 我使用了virtualenv並將我的Django項目移到了這個環境中,但是我看到了另一個設置,其中有一個虛擬環境文件夾和其他項目文件夾。

  • 如何以允許多個站點托管在單個服務器中的方式設置內容?

  • 為什么有人建議使用gunicorn_django -b 0.0.0.0:8000而其他人建議使用gunicorn_django -b 127.0.0.1:8000 我在Amazon EC2實例中對后者進行了測試,但是當前者工作沒有問題時它沒有工作。

  • nginx的配置文件背后的邏輯是什么? 有很多教程使用截然不同的配置文件,我很困惑哪一個更好。 例如,有些人使用alias /path/to/static/folder和其他root /path/to/static/folder 也許您可以共享首選配置文件。

  • 為什么我們在/etc/nginx創建site-availablesites-enabled之間的符號鏈接?

  • 一些最佳實踐一如既往地歡迎:-)

謝謝

您認為哪種“設置”最佳? 我使用了virtualenv並將我的django項目移到了這個環境中,但是我看到了另一個設置,其中有一個虛擬環境文件夾和其他項目文件夾。

virtualenv是一種隔離Python環境的方法; 因此,它在部署中沒有很大的作用 - 但是在開發測試期間,如果不是強烈推薦的話,這是一個要求。

您將從virtualenv獲得的值是,它允許您確保為應用程序安裝了正確版本的庫。 所以你堅持虛擬環境本身並不重要。 請確保您不將其作為源代碼版本控制系統的一部分包含在內。

文件系統布局並不重要。 您將看到許多文章贊美目錄布局的優點,甚至可以克隆的骨架項目作為起點。 我覺得這更像是個人偏好而不是硬性要求。 當然很高興; 但除非你知道原因 ,否則它不會給你的部署過程增加任何價值 - 所以不要這樣做,因為有些博客推薦它,除非它對你的場景有意義。 例如 - 如果您沒有屬於部署工作流的私有PyPi服務器,則無需創建setup.py文件。

如何以允許多個站點托管在單個服務器中的方式設置內容?

您需要做兩件事來進行多個站點設置:

  1. 如果您有SSL,則在端口80和/或端口443上偵聽公共IP的服務器。
  2. 一堆運行實際django源代碼的“進程”。

人們使用nginx作為#1,因為它是一個非常快速的代理,並沒有像Apache這樣的綜合服務器的開銷。 如果您對它感到滿意,可以自由使用Apache。 沒有要求“為多個站點,使用nginx”; 你只需要一個正在偵聽該端口的服務,就知道如何將(代理)重定向到運行實際django代碼的進程。

對於#2,有幾種方法可以啟動這些過程。 gevent / uwsgi是最受歡迎的。 這里唯一要記住的是不要在生產中使用runserver

這些是絕對最低要求。 通常人們會添加某種流程管理器來控制所有運行的“django服務器”(#2)。 在這里你會看到提到的upstartsupervisor 我更喜歡主管,因為它不需要接管整個系統(不像暴發戶)。 然而,再次 - 這不是一個艱難的要求 你可以完美地運行一堆screen會話並解除它們。 缺點是,如果您的服務器重新啟動,您將不得不重新啟動屏幕會話。

我個人會建議:

  1. Nginx為#1
  2. 在uwsgi和gunicorn之間選擇 - 我使用uwsgi。
  3. 管理后端流程的主管
  4. 您托管的每個應用程序的單個系統帳戶(用戶)。

我建議#4的原因是隔離權限; 再次,不是要求。

為什么有人建議使用gunicorn_django -b 0.0.0.0:8000而其他人建議使用gunicorn_django -b 127.0.0.1:8000? 我在Amazon EC2實例中對后者進行了測試,但是當前者工作沒有問題時它沒有工作。

0.0.0.0表示“所有IP地址” - 它是一個元地址(即占位符地址)。 127.0.0.1是始終指向本地計算機的保留地址。 這就是為什么它被稱為“localhost”。 它只能在同一系統上運行的進程訪問。

通常,您有前端服務器(上面列表中的#1)監聽公共IP地址。 應該將服務器明確綁定到一個 IP地址

但是,如果由於某種原因您使用的是DHCP或者您不知道IP地址是什么(例如,它是新配置的系統),您可以告訴nginx / apache /任何其他進程綁定到0.0.0.0 這應該是一個臨時的臨時措施

對於生產服務器,您將擁有靜態IP。 如果您有動態IP(DHCP),則可以保留0.0.0.0 但是很少有你的生產機器可以使用DHCP。

在生產中不建議將gunicorn / uwsgi綁定到此地址。 如果將后端進程(gunicorn / uwsgi)綁定到0.0.0.0 ,它可以“直接”訪問,繞過前端代理(nginx / apache / etc); 有人可以直接請求http://your.public.ip.address:9000/並直接訪問您的應用程序, 特別是如果您的前端服務器(nginx)和后端進程(django / uwsgi / gevent)正在運行機器

如果您不想輕松運行前端代理服務器,則可以自由地執行此操作。

nginx的配置文件背后的邏輯是什么? 有很多教程使用截然不同的配置文件,我很困惑哪一個更好。 例如,有些人使用“alias / path / to / static / folder”和其他人“root / path / to / static / folder”。 也許您可以共享首選配置文件。

您應該了解的關於nginx的第一件事是它不是像Apache或IIS這樣的網絡服務器 這是一個代理人。 所以你會看到不同的術語,如'上游'/'下游'和多個“服務器”被定義。 花點時間先閱讀nginx手冊。

設置nginx有很多種不同的方法; 但是這里有關於aliasroot問題的一個答案。 root是綁定nginx的文檔根目錄(“主目錄”)的顯式指令。 這是當您在沒有像http://www.example.com/這樣的路徑的情況下發出請求時它將查看的目錄

alias意味着“將名稱映射到目錄”。 別名目錄可能不是文檔根目錄的子目錄。

為什么我們在/ etc / nginx中創建站點可用和站點啟用之間的符號鏈接?

這是debian(和像ubuntu一樣的類似debian的系統)的獨特之處。 sites-available列出系統上所有虛擬主機/站點的配置文件。 sites-enabled sites-available sites-enabled符號鏈接“激活”該站點或虛擬主機。 這是一種分離配置文件並輕松啟用/禁用主機的方法。

我不是部署專家,但會分享我使用gevent部署Django的一些做法(盡管應該類似於gunicorn)。

virtualenv非常棒,因為我不會參與其中。 然而,我發現virtualenv-wrapperdocs )非常有用,特別是當你在許多項目上工作時,因為它允許在不同的virtualenv之間輕松切換。 這並不適用於部署環境,但是當我需要使用SSH在服務器上進行故障排除時,我發現這非常有用。 使用它的另一個好處是它管理virtualenv目錄,因此減少了手動工作。 Virtualenvs應該是一次性的,以便在您遇到版本問題或任何其他安裝問題時,您可以轉儲env並創建一個新的。 因此,最好不要在virtualenv中包含任何項目代碼。 它應該分開。

至於設置多個站點, virtualenv幾乎就是答案。 你應該為每個項目都有一個單獨的virutalenv。 只有這一點才能解決許多問題。 然后在部署時,不同的Python進程將運行不同的站點,這可以避免部署之間出現任何可能的沖突。 我特別發現在同一服務器上管理多個站點非常有用的一個工具是supervisordocs )。 它為啟動,停止和重新啟動不同的Django實例提供了一個簡單的界面。 它還能夠在失敗或計算機啟動時自動重啟進程。 因此,舉例來說,如果引發了一些異常而沒有任何異常,整個網站都會崩潰。 主管將捕獲它並將自動重啟Django實例。 以下是示例管理程序(單個進程)配置:

[program:foo]
command=/path/toviertualenv/bin/python deploy.py
directory=/path/where/deploy.py/is/located/
autostart=true
autorestart=true
redirect_stderr=True
user=www

對於Nginx,我知道一開始可能會讓人不知所措。 我發現Nginx的很有用。 它解釋了所有主要的nginx指令。

在我的nginx安裝中,我發現最好的做法是只在nginx.conf文件中設置核心配置,然后我有一個單獨的文件夾sites ,我為每個托管的站點保留nginx配置。 然后我只在核心配置文件中包含該文件夾中的所有文件。 我使用指令include sites/+*.conf; 這樣它只包含sites文件夾中以+符號開頭的文件。 這樣只需通過文件名我可以控制哪些配置文件被加載。 因此,如果我想禁用某個站點,我只需要重命名配置文件並重新啟動nginx。 在你的問題中,不確定你的意思是“在/ etc / nginx中啟用了站點可用和站點之間的符號鏈接”,因為這些是Apache命名文件夾,但它們完成了與include指令類似的任務。

至於rootalias指令,它們幾乎是相同的,除非計算它們的根。 alias ,無論在丟棄的location如何,而在根中不是。 您擁有以下nginx配置的圖片:

location /static {
    alias /some/path/;
}
location /static2 {
    root /some/other/path/;
}

如果用戶轉到這些URL,那么nginx將嘗試在系統的以下位置查找文件:

/static/hello/world.pdf => /some/path/hello/world.pdf
/static2/hello/world.pdf => /some/other/path/static2/hello/world.pdf

這是nginx站點的簡單配置:

server {
    server_name .foodomain.com;
    listen 80;

    access_log logs/foodomain.log;

    gzip                on;
    gzip_http_version   1.0;
    gzip_comp_level     2;
    gzip_proxied        any;
    gzip_min_length     1100;
    gzip_buffers        16 8k;
    gzip_types          text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    # Some version of IE 6 don't handle compression well on some mime-types, so just disable for them
    gzip_disable "MSIE [1-6].(?!.*SV1)";

    # Set a vary header so downstream proxies don't send cached gzipped content to IE6
    gzip_vary on;

    location / {
        proxy_read_timeout      30s;
        proxy_pass              http://localhost:8000;
        proxy_set_header        Host                 $host;
        proxy_set_header        User-Agent           $http_user_agent;
        proxy_set_header        X-Real-IP            $remote_addr;
    }

    location /media {
        alias   /path/to/media/;
        expires 1y;
    }

    location /static {
        autoindex on;
        expires   1y;
        alias     /path/to/static/;
    }

     location /favicon.ico {
        alias /path/to/favicon.ico;
    }
}

希望這對你有所幫助。

好吧,就你在問題中提出的最佳實踐而言,我無法幫助分享一個對我來說有奇跡的工具! 我自己曾經在幾個網站的gunicorn,nginx,supervisorD的幾個配置文件中感到困惑! 但我渴望以某種方式自動化整個過程,以便我可以對我的應用程序/站點進行更改並立即進行部署。 它的名字是django-fagungis。 您可以在此處找到有關Django Deployment自動化體驗的詳細信息。 我剛剛配置了一個fabfile.py ONCE(django-fagungis使用fabric來自動完成整個過程並在你的遠程服務器上創建一個virtualenv, 非常方便管理托管在單個服務器上的幾個站點的依賴關系。它使用nginx,gunicorn和supervisorD處理Django項目/站點部署)和django-fagungis從bitbucket克隆我的最新項目(我用於顛覆)並將其部署在我的遠程服務器上,我只需要在我的本地機器的shell上輸入三個命令! 對我來說,這已經證明是Django部署的最佳和最輕松的自由練習。

檢查這是否為Django項目所需的最小gunicorn和nginx配置。 http://agiliq.com/blog/2013/08/minimal-nginx-and-gunicorn-configuration-for-djang/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM