Django'yu gunicorn ve nginx ile dağıtmak


81

Bu geniş bir soru ama kanonik bir cevap almak istiyorum. Ben kullanarak bir site dağıtmak için uğraşıyorlar gunicorn ve nginx içinde Django . Tonlarca öğreticiyi okuduktan sonra başarılı oldum, ancak izlediğim adımların bir siteyi sorunsuz bir şekilde çalıştırmak için yeterince iyi olduğundan veya bunu yapmanın daha iyi yolları olduğundan emin olamıyorum. Bu belirsizlik can sıkıcı.

Bu yüzden yeni başlayanlar için çok detaylı ve iyi anlatılmış bir cevap arıyorum. Ne bildiğimi ve neyi bilmediğimi çok fazla açıklamak istemiyorum çünkü bu, cevapları biraz çarpıtabilir ve diğer insanlar cevaplarınızdan daha az ölçüde faydalanabilir. Ancak, bahsetmek istediğim bazı şeyler şunlardır:

  • En çok hangi "kurulumun" işe yaradığını gördünüz? Virtualenv kullandım ve Django projemi bu ortama taşıdım , ancak sanal ortamlar ve diğer projeler için bir klasörün olduğu başka kurulumlar gördüm.

  • İşleri birkaç sitenin tek bir sunucuda barındırılmasına izin verecek şekilde nasıl kurabilirim?

  • Neden bazıları kullanmayı öneriyor gunicorn_django -b 0.0.0.0:8000ve diğerleri öneriyor gunicorn_django -b 127.0.0.1:8000? İkincisini bir Amazon EC2 bulut sunucusunda test ettim, ancak eski sorunsuz çalışırken işe yaramadı.

  • Nginx'in yapılandırma dosyasının arkasındaki mantık nedir? Büyük ölçüde farklı yapılandırma dosyalarını kullanan o kadar çok öğretici var ki hangisinin daha iyi olduğu konusunda kafam karıştı. Örneğin, bazı insanlar kullanır alias /path/to/static/folderve diğerleri root /path/to/static/folder. Belki tercih ettiğiniz konfigürasyon dosyasını paylaşabilirsiniz.

  • Neden arasında site-availableve sites-enablediçinde bir sembolik bağ oluşturuyoruz /etc/nginx?

  • Bazı en iyi uygulamalar her zaman olduğu gibi memnuniyetle karşılanmaktadır :-)

Teşekkürler


Bu nginx ve gunicorn / uwsgi ile ilgili git üzerine bir örnek gönderebilir misiniz? Benim gibi yeni öğrenenler için daha faydalı olacaktır.
Shiva

@Shiva Aslında, miki725'in cevabı bir yapılandırma dosyasının çok eksiksiz bir örneğini içerir. Nginx'te neler olup bittiğine dair ayrıntılı bir giriş istiyorsanız, size <a href=" amazon.com/Nginx-HTTP-Server-Cl%C3%A9ment-Nedelcu/dp/… kitap</a> öneririm. gunicorn entegrasyonu çok basit O özetlenmiştir <a href=" docs.djangoproject.com/en/dev/howto/deployment/wsgi/gunicorn/...>.
Robert Smith

Yanıtlar:


106

En çok hangi "kurulumun" işe yaradığını gördünüz? Virtualenv kullandım ve django projemi bu ortama taşıdım, ancak sanal ortamlar ve diğer projeler için klasörlerin olduğu başka bir kurulum gördüm.

virtualenv, Python ortamlarını izole etmenin bir yoludur; bu nedenle, dağıtımda oynayacak büyük bir rolü yoktur - ancak geliştirme ve test sırasında , şiddetle tavsiye edilmiyorsa bir gerekliliktir.

Virtualenv'den alacağınız değer, uygulama için kitaplıkların doğru sürümlerinin kurulduğundan emin olmanızı sağlamasıdır. Yani sanal çevrenin kendisini nereye yapıştırdığınız önemli değil. Bunu kaynak kodu versiyonlama sisteminin bir parçası olarak eklemediğinizden emin olun.

Dosya sistemi düzeni kritik değildir. Dizin düzenlerinin erdemlerini ve hatta başlangıç ​​noktası olarak klonlayabileceğiniz iskelet projelerini yücelten birçok makale göreceksiniz. Bunun zor bir gereklilikten çok kişisel bir tercih olduğunu düşünüyorum. Elbette olması güzel; ancak nedenini bilmiyorsanız , dağıtım sürecinize herhangi bir değer katmaz - öyleyse bunu yapmayın çünkü senaryonuz için mantıklı gelmedikçe bazı bloglar öneriyor. Örneğin setup.py, dağıtım iş akışınızın parçası olan özel bir PyPi sunucunuz yoksa bir dosya oluşturmanıza gerek yoktur .

İşleri birkaç sitenin tek bir sunucuda barındırılmasına izin verecek şekilde nasıl kurabilirim?

Birden çok site kurulumu yapmanız gereken iki şey vardır:

  1. SSL'niz varsa bağlantı noktası 80 ve / veya bağlantı noktası 443'teki genel IP'yi dinleyen bir sunucu.
  2. Gerçek django kaynak kodunu çalıştıran bir grup "işlem".

İnsanlar # 1 için nginx kullanıyor çünkü çok hızlı bir proxy ve Apache gibi kapsamlı bir sunucunun ek yüküyle gelmiyor. Rahatsanız Apache'yi kullanmakta özgürsünüz. "Birden fazla site için nginx kullanın" şartı yoktur; sadece o bağlantı noktasında dinleyen, gerçek django kodunu çalıştıran süreçlerinize nasıl yönlendirileceğini (proxy) bilen bir hizmete ihtiyacınız var.

# 2 için bu işlemleri başlatmanın birkaç yolu var. gevent / uwsgi en popüler olanlardır. Burada hatırlanması gereken tek şey , üretimde runserver kullanmamaktır .

Bunlar mutlak minimum gereksinimlerdir. Tipik olarak insanlar, çalışan tüm "django sunucularını" (# 2) kontrol etmek için bir çeşit işlem yöneticisi ekler. Burada göreceksiniz upstartve supervisorbahsedeceksiniz. Tüm sistemi devralması gerekmediği için süpervizörü tercih ederim (upstart'ın aksine). Ancak, yine - bu zor bir gereklilik değildir . Bir sürü screenseansı mükemmel bir şekilde yürütebilir ve onları ayırabilirsiniz. Olumsuz tarafı, sunucunuz yeniden başlatılırsa, ekran oturumlarını yeniden başlatmanız gerekmesidir.

Şahsen şunları tavsiye ederim:

  1. # 1 için Nginx
  2. Uwsgi ve gunicorn arasında seçim yap - ben uwsgi kullanıyorum.
  3. arka uç süreçlerini yönetmek için gözetmen .
  4. Barındırdığınız her uygulama için ayrı sistem hesapları (kullanıcılar).

# 4'ü önermemin nedeni izinleri izole etmektir; yine, bir gereklilik değil.

Neden bazı insanlar gunicorn_django -b 0.0.0.0:8000 kullanmanızı önerirken diğerleri gunicorn_django -b 127.0.0.1:8000'i önermektedir? İkincisini bir Amazon EC2 bulut sunucusunda test ettim, ancak eski sorunsuz çalışırken işe yaramadı.

0.0.0.0"tüm IP adresleri" anlamına gelir - bir meta adres (yani, bir yer tutucu adresi). 127.0.0.1her zaman yerel makineyi gösteren ayrılmış bir adrestir. Bu nedenle "localhost" olarak adlandırılır. Yalnızca aynı sistem üzerinde çalışan işlemlere erişilebilir.

Genelde genel IP adresini dinleyen ön uç sunucunuz (yukarıdaki listede 1 numara) vardır. Sen should açıkça sunucunun bağlamak biri IP adresine .

Bununla birlikte, herhangi bir nedenle DHCP üzerindeyseniz veya IP adresinin ne olacağını bilmiyorsanız (örneğin, yeni sağlanan bir sistem), nginx / apache / diğer herhangi bir işleme bağlanmasını söyleyebilirsiniz 0.0.0.0. Bu geçici bir geçici önlem olmalıdır .

Üretim sunucuları için statik bir IP'ye sahip olacaksınız. Dinamik bir IP'niz (DHCP) varsa, içeri girebilirsiniz 0.0.0.0. Yine de üretim makineleriniz için DHCP'ye sahip olmanız çok nadirdir.

Üretimde gunicorn / uwsgi'nin bu adrese bağlanması tavsiye edilmemektedir . Arka uç sürecinizi (gunicorn / uwsgi) ile bağlarsanız 0.0.0.0, ön uç proxy'nizi (nginx / apache / vb.) Atlayarak "doğrudan" erişilebilir hale gelebilir; özellikle ön uç sunucunuz (nginx) ve arka uç işleminiz (django / uwsgi / gevent) aynı makinede çalışıyorsa, birisi http://your.public.ip.address:9000/uygulamanızı doğrudan isteyebilir ve ona erişebilir .

Yine de bir ön uç proxy sunucusu çalıştırma zorluğuna sahip olmak istemiyorsanız, bunu yapmakta özgürsünüz.

Nginx'in yapılandırma dosyasının arkasındaki mantık nedir? Büyük ölçüde farklı yapılandırma dosyalarını kullanan o kadar çok öğretici var ki hangisinin daha iyi olduğu konusunda kafam karıştı. Örneğin, bazı kişiler "takma ad / yol / / statik / klasör" ve diğerleri "kök / yol / / statik / klasör" kullanır. Belki tercih ettiğiniz konfigürasyon dosyasını paylaşabilirsiniz.

Nginx hakkında bilmeniz gereken ilk şey, bunun Apache veya IIS gibi bir web sunucusu olmamasıdır . Bu bir vekildir. Dolayısıyla, "yukarı akış" / "aşağı akış" ve birden çok "sunucu" gibi farklı terimlerin tanımlandığını göreceksiniz. Biraz zaman ayırın ve önce nginx kılavuzunu gözden geçirin.

Nginx'i kurmanın birçok farklı yolu vardır; ama burada sorunuzun bir cevaptır aliasvs. root. rootnginx'in belge kökünü ("ev dizini") bağlayan açık bir yönergedir. Bu, yolu olmayan bir istek verdiğinizde bakacağı dizindir.http://www.example.com/

alias"bir ismi bir dizine eşle" anlamına gelir. Adlandırılmış dizinler , belge kökünün bir alt dizini olamaz .

Neden / etc / nginx içinde site kullanılabilir ve siteler arasında bir sembolik bağlantı oluşturuyoruz?

Bu, debian'a (ve ubuntu gibi debian benzeri sistemlere) özgü bir şeydir. sites-availablesistemdeki tüm sanal ana bilgisayarlar / siteler için yapılandırma dosyalarını listeler. A sembolik link sites-enablediçin sites-availablesitenin veya sanal konak "aktive". Yapılandırma dosyalarını ayırmanın ve ana bilgisayarları kolayca etkinleştirmenin / devre dışı bırakmanın bir yoludur.


1
Mükemmel cevap! Birçok soru açıklığa kavuşturuldu. Sunucuyu bir IP adresine açıkça bağlayarak ne demek istediğinizi ve gunicorn / uwsgi'nin 0.0.0.0'a bağlanması gerektiğini biraz daha detaylandırabilir misiniz (veya bir örnek ekleyebilir misiniz? Ne yazık ki, yaptığım şeyin bu olduğunu düşünüyorum. Teşekkürler!
Robert Smith

7
Tipik bir bilgisayarın en az iki IP adresi olacaktır: 127.0.0.1ve ona ağ tarafından atanan IP adresi ; bu minimumdur - makinenizin birden çok arabirimi ve birden çok IP adresi olabilir. Web sunucunuzu (veya herhangi bir işlemi gerçekten) yapılandırmalısınız; tek bir IP adresini dinlemek - açık olmakla kastettiğim bu. Bağlandığınızda 0.0.0.0, programa makinenize atanabilecek yenileri de dahil olmak üzere tüm IP adreslerini dinlemesini söylüyorsunuz . Bu, çeşitli nedenlerden dolayı iyi bir uygulama değildir (güvenlik bunlardan biridir).
Burhan Khalid

Anladım. Gunicorn'u zaten doğru şekilde yapılandırdım. Çok teşekkür ederim!
Robert Smith

nginx statik içerik sunabilir.
Marcin

sunucu, sunucu adresini hangi dosyada yapılandırdığımızı nasıl bilecek/etc/nginx/sites-enabled
Shiva

11

Ben bir dağıtım gurusu değilim, ancak Django'yu gevent ile konuşlandırmaya yönelik bazı uygulamalarımı paylaşacağım (yine de gunicorn'a benzer olmalıdır).

virtualenvgirmeyeceğim nedenlerden dolayı harika. Bununla birlikte, virtualenv-wrapper( docs ) çok yararlı buldum , özellikle birçok proje üzerinde çalışırken, farklı sanal ortamlar arasında kolay geçişe izin verdiği için. Bu, dağıtım ortamı için gerçekten geçerli değil, ancak SSH kullanarak sunucuda sorun gidermem gerektiğinde, bunu çok yararlı buldum. Kullanmanın diğer bir avantajı, virtualenv dizinini yönetmesidir, bu nedenle sizin için daha az manuel çalışma. Virtualenv'lerin tek kullanımlık olması amaçlanmıştır, böylece sürüm sorunlarınız veya başka herhangi bir yükleme sorununuz olması durumunda, env'i atabilir ve yeni bir tane oluşturabilirsiniz. Sonuç olarak, proje kodunuzun hiçbirini virtualenv'e dahil etmemek en iyi uygulamadır. Ayrı tutulmalıdır.

Birden fazla site kurmaya gelince virtualenv, cevap hemen hemen budur. Her proje için ayrı bir virutalenv'e sahip olmalısınız. Sadece bu tek başına birçok sorunu çözebilir. Daha sonra dağıttığınızda, farklı bir Python işlemi farklı siteler çalıştırır ve bu da dağıtımlar arasındaki olası çatışmaları önler. Aynı sunucuda birden çok siteyi yönetmede özellikle yararlı bulduğum bir araç supervisor( docs). Farklı Django örneklerini başlatmak, durdurmak ve yeniden başlatmak için kolay bir arayüz sağlar. Ayrıca, başarısız olduğunda veya bilgisayar başladığında bir işlemi otomatik olarak yeniden başlatabilir. Örneğin, bir istisna ortaya çıkarsa ve hiçbir şey onu yakalayamazsa, tüm web sitesi çökebilir. Süpervizör bunu yakalayacak ve Django örneğini otomatik olarak yeniden başlatacaktır. Aşağıda örnek bir gözetmen programı (tek işlem) yapılandırması verilmiştir:

[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 için ilk başta bunun çok zor olabileceğini biliyorum. Nginx kitabını çok faydalı buldum . Tüm önemli nginx direktiflerini açıklar.

Nginx kurulumumda, en iyi uygulamanın nginx.confdosyada yalnızca temel yapılandırmaları kurmak olduğunu ve ardından sitesbarındırdığım sitelerin her biri için nginx yapılandırmalarını sakladığım ayrı bir klasörüm olduğunu buldum. Sonra o klasördeki tüm dosyaları çekirdek yapılandırma dosyasına ekliyorum. Direktifi kullanıyorum include sites/+*.conf;. Bu şekilde, yalnızca klasör +içinde sembolle başlayan dosyaları içerir sites. Bu şekilde sadece dosya adına göre hangi yapılandırma dosyalarının yükleneceğini kontrol edebilirim. Dolayısıyla, belirli bir siteyi devre dışı bırakmak istersem, yapılandırma dosyasını yeniden adlandırmam ve nginx'i yeniden başlatmam gerekir. Apache adlı klasörler olduklarından, sorunuzda "site-kullanılabilir ve / etc / nginx içinde site-etkinleştirilmiş siteler arasındaki sembolik bağlantı" ile ne demek istediğinizden tam olarak emin değilsiniz, ancak bunlar includeyönerge ile benzer görevi yerine getiriyorlar .

Gelince rootve aliasdirektifler, onlar hemen hemen kök hesaplanır yerler dışında aynıdır. İçinde alias, içinde ne varsa locationdüşürülür, oysa kökte değildir. Aşağıdaki nginx yapılandırmasına sahip olduğunuz resmi:

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

Kullanıcı bu URL'lere giderse, nginx sistemde aşağıdaki yerlerde bulunan dosyaları aramaya çalışır:

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

Bu, nginx sitesi için basit bir yapılandırmadır:

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;
    }
}

Umarım bu size biraz yardımcı olur.


Aslında cevabınız çok yardımcı oluyor! Süpervizör kulağa harika geliyor ve bu, blogcular arasında fikir birliği olduğu görünen birkaç şeyden biri. Sanal ortamlar ve sarmalayıcı hakkında harika tavsiyeler. Karışıma virtualenv-wrapper eklemek istedim ancak gereksiz yere bu sorudaki karmaşıklığı artırmak istemedim. Site erişimli ve site destekli olarak, nginx bu dizinleri içerir. Nginx için yapılandırma dosyanızı nerede oluşturursunuz? Django projenizin içinde mi?
Robert Smith

Onları şahsen nginx config klasöründe tutuyorum. Benim durumumda öyle /usr/local/nginx/config/sites. Doğru mu yoksa daha iyi bir yöntem mi olduğundan emin değilim. Onları orada tutmamın nedeni, eğer onu dışarı çıkarırsam, bir şekilde onu nginx'e dahil etmem gerek, el ile includedirektif ekleyerek veya sembolik bağlantılar oluşturarak. Her iki durumda da, el emeği, bu yüzden onu sadece ana yapılandırma yerinde tutuyorum.
miki725

Tavsiye ettiğiniz kitabı okuyorum :-) Harika ve hatırlayacağınız gibi, /sites/*.conf bunu yapmanın önerilen yollarından biri. Her neyse, cevabınız için teşekkürler.
Robert Smith

Rica ederim. Kitap hakkında pek yararlı olmadığını düşündüğüm bir bölüm, Django'nun nginx ile nasıl kullanılacağıydı. Kitap, proxy geçişi kullanmak kadar düzgün olmayan fastcgi'yi kullanmanızı önerir. Eğer Bölüm 6. atlayabilirsiniz Yani
miki725

Kitabı okumayı yeni bitirdim. Bu harika. Aslında 6. bölümü okudum çünkü hoy fastcgi'nin işe yaradığını bilmek istedim, ama haklısın ... pek faydalı olmadı. Teşekkürler!
Robert Smith

2

Sorunuzda sorduğunuz en iyi uygulamalar söz konusu olduğunda, kelimenin tam anlamıyla benim için harikalar yaratan bir aracı paylaşmaktan kendimi alamıyorum! Ben de birkaç site için birkaç gunicorn, nginx, supervisorD yapılandırma dosyasında kafam karışırdı! Ancak tüm süreci bir şekilde otomatikleştirmek için can atıyordum, böylece uygulamamda / sitemde değişiklikler yapıp anında dağıtabilirim. Adı django-fagungis. Django Dağıtım otomasyonu ile ilgili deneyimimin ayrıntılarını burada bulabilirsiniz . Az önce bir fabfile.py yapılandırdım (django-fagungis tüm süreci otomatikleştirmek için kumaş kullanır ve uzak sunucunuzda ÇOK kullanışlı olan bir virtualenv oluştururtek bir sunucuda barındırılan birkaç sitenin bağımlılıklarını yönetmek için. Django projesini / site dağıtımını idare etmek için nginx, gunicorn ve supervisorD kullanır) ve django-fagungis, en son projemi bitbucket'ten klonlar (bunu yıkmak için kullanıyorum) ve uzak sunucuma dağıtır ve sadece kabukta üç komut girmem gerekiyor yerel makinemin ve o! Benim için bu, Django konuşlandırması için en iyi ve sorunsuz uygulama haline geldi.


Teşekkürler!. Bi 'bakacağım.
Robert Smith

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.