81 votes

Le déploiement de Django avec gunicorn et nginx

C'est une vaste question, mais je voudrais obtenir une réponse canonique. J'ai essayé de déployer un site à l'aide de gnunicorn et nginx dans Django. Après avoir lu des tonnes de tutoriels que j'ai eu du succès, mais je ne peux pas être sûr que les étapes que j'ai suivies sont assez bonnes pour exécuter un site sans problèmes ou peut-être il ya de meilleures façons de le faire. Cette incertitude est ennuyeux.

C'est pourquoi je suis à la recherche d'un son très détaillé et bien expliqué réponse pour les débutants. Je ne veux pas expliquer trop ce que je sais et ce que je ne sais pas, car cela pourrait fausser les réponses un peu et d'autres personnes pourraient bénéficier à un degré moindre de vos réponses. Cependant, certaines choses que j'aimerais voir mentionnés sont:

  • Ce que "setup" avez-vous vu à l'œuvre le meilleur? J'ai utilisé virtualenv et déplacé mon projet django à l'intérieur de cet environnement, toutefois, j'ai vu un autre là où il y a un dossier pour les environnements virtuels, et d'autres projets.

  • Comment puis-je configurer les choses d'une manière qui permet à plusieurs sites d'être hébergé dans un serveur unique?

  • Pourquoi certaines personnes suggèrent d'utiliser gunicorn_django -b 0.0.0.0:8000 et d'autres suggèrent gunicorn_django -b 127.0.0.1:8000? J'ai testé le dernier dans une instance Amazon EC2, mais il ne fonctionne pas alors que le premier a fonctionné sans problème.

  • Quelle est la logique derrière le fichier de configuration de nginx? Il ya tellement de nombreux tutoriels en utilisant radicalement différents fichiers de configuration que je suis confus sur qui est le meilleur. Par exemple, certaines personnes utilisent des "alias /chemin/vers/static/dossier" et autres "root /chemin/vers/static/dossier". Peut-être que vous pouvez partager votre préféré fichier de configuration.

  • Pourquoi pouvons-nous créer un lien symbolique entre le site et disponible sites-enabled /etc/nginx?

  • Certaines des meilleures pratiques sont toujours les bienvenus :-)

Merci

105voto

Burhan Khalid Points 50578

Ce que "setup" avez-vous vu à l'œuvre le meilleur? J'ai utilisé virtualenv et déplacé mon projet django à l'intérieur de cet environnement, toutefois, j'ai vu un autre là où il y a un dossier pour les environnements virtuels et d'autres pour projets.

virtualenv est un moyen d'isoler Python environnements; en tant que tel, il n'a pas un grand rôle à jouer au déploiement - toutefois, au cours du développement et de test , il est une exigence si pas très recommandé.

La valeur de virtualenv est qu'il vous permet de vous assurer que les versions correctes des bibliothèques sont installées pour l'application. Donc, il n'a pas d'importance où vous vous en tenez l'environnement virtuel lui-même. Assurez-vous de ne pas l'inclure dans le code source du système de gestion de versions.

Le système de fichiers de mise en page n'est pas critique. Vous verrez beaucoup d'articles vantant les vertus de mises en page du répertoire et même squelette de projets que vous pouvez cloner comme un point de départ. J'ai l'impression que c'est plus une question de préférence personnelle qu'une dure exigence. Sûr que c'est agréable d'avoir; mais, sauf si vous savez pourquoi, il ne pas ajouter de la valeur à votre processus de déploiement - il ne faut pas le faire parce que certains blog le recommande sauf si elle fait sens pour votre scénario. Par exemple, pas besoin de créer un setup.py le fichier si vous n'avez pas de privé PyPi serveur qui fait partie de votre flux de travaux de déploiement.

Comment puis-je configurer les choses d'une manière qui permet à plusieurs sites hébergés dans un seul serveur?

Il y a deux choses que vous devez faire plusieurs installations de sites:

  1. Un serveur qui écoute sur l'adresse IP publique sur le port 80 et/ou le port 443 si vous avez SSL.
  2. Un tas de "processus" qui sont en cours d'exécution le réel django code source.

Les gens utilisent nginx pour le #1, en raison de sa très rapide proxy et il ne vient pas avec la surcharge d'un complet serveur comme Apache. Vous êtes libre de les utiliser Apache si vous êtes à l'aise avec elle. Il n'est pas nécessaire que "pour plusieurs sites, l'utilisation de nginx", vous avez juste besoin d'un service qui est à l'écoute sur ce port, sait comment faire pour rediriger (proxy) de votre processus de l'exécution de la réelle django code.

Pour le #2, il ya quelques façons de commencer ces processus. gevent/uwsgi sont les plus populaires. La seule chose à retenir ici est de ne pas utiliser runserver dans la production.

Ceux-ci sont le minimum absolu exigences. Généralement les gens ajouter une sorte de gestionnaire de processus pour le contrôle de tous les "django serveurs" (#2) en cours d'exécution. Ici, vous verrez upstart et supervisor mentionné. Je préfère superviseur comme il n'a pas besoin de prendre plus de l'ensemble du système (contrairement à arriviste). Cependant, encore une fois - ce n'est pas un dur exigence. Vous pourriez parfaitement exécuter un tas de screen des séances et de l'abîmer. L'inconvénient est, si votre serveur est redémarré, vous devez relancer l'écran des sessions.

Personnellement, je recommanderais:

  1. Nginx pour le #1
  2. Faites votre choix entre uwsgi et gunicorn - je utiliser uwsgi.
  3. superviseur de la gestion du processus serveur.
  4. Système individuel comptes (utilisateurs) pour chaque application que vous hébergez.

La raison pour laquelle je recommande #4 est d'isoler les autorisations; encore une fois, pas une obligation.

Pourquoi certaines personnes suggèrent d'utiliser gunicorn_django -b 0.0.0.0:8000 et d'autres suggèrent gunicorn_django -b 127.0.0.1:8000? J'ai testé le dernier dans une instance Amazon EC2, mais il ne fonctionne pas alors que le premier a travaillé sans problème.

0.0.0.0 signifie "toutes les adresses IP" - un méta adresse (qui est, un espace réservé à l'adresse). 127.0.0.1 est une adresse réservée qui pointe toujours vers la machine locale. C'est pourquoi elle est appelée "localhost". Il n'est accessible que pour les processus en cours d'exécution sur le même système.

En général, vous avez le serveur frontal (#1 dans la liste ci-dessus) à l'écoute sur l'adresse IP publique. Vous devez explicitement lier le serveur à une adresse IP.

Toutefois, si pour quelque raison vous êtes sur DHCP ou si vous ne connaissez pas l'adresse IP (par exemple, récemment mise en service du système), vous pouvez dire nginx/apache/tout autre procédé pour lier 0.0.0.0. Cela devrait être un arrêt temporaire-de l'écart de mesure.

Pour les serveurs de production, vous aurez une adresse IP statique. Si vous avez une adresse IP dynamique (DHCP), vous pouvez les laisser en 0.0.0.0. Il est très rare que vous aurez DHCP pour vos machines de production.

La liaison gunicorn/uwsgi à cette adresse n'est pas recommandé dans la production. Si vous liez votre backend processus (gunicorn/uwsgi) 0.0.0.0, il peut devenir accessible "directement", en contournant votre front-end proxy (nginx/apache/etc); quelqu'un pourrait il suffit de demander http://your.public.ip.address:9000/ et accéder à votre demande directement, surtout si votre serveur frontal (nginx) et votre dos en fin de processus (django/uwsgi/gevent) sont en cours d'exécution sur la même machine.

Vous êtes libre de le faire si vous ne voulez pas avoir le souci de faire fonctionner un serveur proxy frontal.

Quelle est la logique derrière le fichier de configuration de nginx? Il ya tellement de nombreuses des tutoriels en utilisant radicalement différents fichiers de configuration que je suis confus sur qui est le meilleur. Par exemple, certaines personnes utilisent des "alias /chemin/vers/static/dossier" et autres "root /chemin/vers/static/dossier". Peut-être que vous pouvez partager votre préféré fichier de configuration.

La première chose que vous devez savoir à propos de nginx est que c'est pas un serveur web comme Apache ou IIS. C'est un proxy. Donc, vous allez voir les différents termes comme "en amont" et "aval" et plusieurs "serveurs" en cours de définition. Prendre un certain temps et passer par la nginx manuel.

Il ya beaucoup de façons différentes de mettre en place nginx; mais voici une réponse à votre question sur alias vs root. root est explicite directive qui la lie à la racine du document (le "home directory") de nginx. C'est le répertoire, il va regarder lorsque vous faites une demande sans chemin d'accès, comme http://www.example.com/

alias signifie "mapper un nom dans un répertoire". Alias répertoires ne peut pas être un sous-répertoire de la racine du document.

Pourquoi pouvons-nous créer un lien symbolique entre le site et disponible sites-enabled dans /etc/nginx?

C'est quelque chose d'unique à debian (et debian-like systèmes comme ubuntu). sites-available les listes des fichiers de configuration pour tous les hôtes virtuels/sites sur le système. Un lien symbolique à partir de sites-enabled de sites-available "active" de ce site ou de l'hôte virtuel. C'est un moyen de séparer les fichiers de configuration et facilement activer/désactiver les hôtes.

11voto

miki725 Points 6976

Je ne suis pas un déploiement guru, mais aussi permettra de partager certaines de mes pratiques pour le déploiement de Django avec gevent (devrait être similaire à gunicorn tout de même).

virtualenv est grande pour des raisons que je ne vais pas entrer dans. J'ai cependant trouvé virtualenv-wrapper (docs) très utile, surtout lorsque vous travaillez sur de nombreux projets car il permet de facile de basculer entre les différents virtualenvs. Ce n'est pas vraiment s'appliquer à l'environnement de déploiement, cependant quand j'ai besoin de résoudre les problèmes sur le serveur à l'aide de SSH, j'ai trouvé cela très utile. Un autre avantage c'est qu'il gère le virtualenv répertoire, donc moins de travail manuel pour vous. Virtualenvs sont destinés à être à usage unique, de sorte que dans le cas où vous avez des problèmes de version, ou de toute autre installation des questions, vous pouvez simplement le jeter à l'env et en créer un nouveau. Comme le résultat, il est préférable de ne pas inclure votre code de projet dans le virtualenv. Il devrait être séparés.

Comme pour l'installation de plusieurs sites, virtualenv est à peu près la réponse. Vous devriez avoir une virutalenv pour chaque projet. Juste que seul peut résoudre de nombreux problèmes. Ensuite, lorsque vous déployez, un autre Python processus sera lancé différents sites qui évite tout conflit entre les déploiements. Un outil que j'ai surtout trouvé très utile dans la gestion de plusieurs sites sur le même serveur est - supervisor (docs). Il fournit une interface simple pour le démarrage, l'arrêt et le redémarrage de différentes Django instances. Il est également capable d'auto-redémarrage d'un processus lorsqu'il échoue ou lorsque l'ordinateur démarre. Ainsi, par exemple, si une exception est levée et rien ne l'attrape, l'ensemble du site web peut descendre. Superviseur attraper le et redémarrez l'instance de Django automatiquement. Voici un exemple de programme superviseur (un seul processus) config:

[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

Pour Nginx, je sais qu'il peut être écrasante au premier abord. J'ai trouvé Nginx livre très utile. Il explique tous les grands nginx directives.

Dans mon nginx installer, j'ai trouvé la meilleure pratique consiste à l'installation de base uniquement les configs dans l' nginx.conf le fichier et puis j'ai un dossier distinct sites où j'ai garder la nginx configs pour chacun des sites, j'ai hôte. Je viens d'inclure tous les fichiers de ce dossier dans la base de fichier de config. J'utilise la directive include sites/+*.conf;. De cette façon, il comprend uniquement les fichiers commençant par + symbole dans l' sites le dossier. De cette façon, juste par le nom de fichier que je peux contrôler les fichiers de config d'être chargé. Donc, si je souhaite désactiver un certain site, je viens de renommer le fichier de configuration et redémarrer nginx. Pas vraiment sûr de ce que vous entendez par "lien entre le site et disponible sites-enabled /etc/nginx" dans votre question, car ceux-ci sont Apache nommé dossiers, mais qu'ils accomplissent des tâches similaires que l' include directive.

Comme pour root et alias directives, ils sont à peu près les mêmes, sauf lorsque leur racine est calculé. En alias, que ce soit dans l' location dans baissé, tandis que dans la racine en elle pas. L'Image que vous avez la config nginx:

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

Si l'utilisateur accède à ces Url, puis nginx vais essayer de chercher les fichiers dans les endroits suivants sur le système:

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

C'est une simple config de nginx site:

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

J'espère que cela vous aide un peu.

2voto

Ali Raza Bhayani Points 395

Eh bien, pour que les meilleures pratiques sont concernés, vous avez demandé à votre question, je ne peux m'empêcher de partager un outil qui fait des merveilles pour moi, littéralement! J'ai moi-même utilisé pour se confondre dans plusieurs fichiers de configuration de gunicorn, nginx, supervisorD pour plusieurs sites! Mais j'avais envie de quelque sorte automatiser l'ensemble du processus afin que je puisse apporter des modifications à mon app/site et de le déployer instantanément. Son nom est django-fagungis. Vous pouvez trouver les détails de mon expérience avec le Django d'automatisation du Déploiement ici. J'ai juste configuré un fabfile.py une FOIS (django-fagungis utilise un tissu d'automatiser l'ensemble du processus et fait un virtualenv dans votre serveur distant qui est TRÈS pratique pour gérer les dépendances de plusieurs sites hébergés sur un serveur unique. Il utilise nginx, gunicorn et supervisorD pour gérer le projet Django/déploiement de site) et django-fagungis clones de mon dernier projet de bitbucket (que j'utilise pour subversioning) et la déploie sur mon serveur distant et je n'ai qu'à entrer les trois commandes shell de ma machine et qu'elle!! Pour moi, cela s'est avéré pour être le meilleur et sans tracas pratique pour Django de déploiement.

2voto

akshar Points 2286

Vérifiez ce pour un minimum de gunicorn et nginx configuration requise pour un projet Django. http://agiliq.com/blog/2013/08/minimal-nginx-and-gunicorn-configuration-for-djang/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X