Comment servir les applications Django avec uWSGI et Nginx sur Ubuntu 14.04

introduction

Django est un puissant framework Web qui peut vous aider à faire décoller votre application ou votre site Web Python. Django inclut un serveur de développement simplifié pour tester votre code localement, mais pour tout ce qui est légèrement lié à la production, un serveur Web plus sécurisé et plus puissant est requis.

Dans ce guide, nous montrerons comment installer et configurer certains composants sur Ubuntu 14.04 pour prendre en charge et servir les applications Django. Nous allons configurer le serveur de conteneur d’application uWSGI pour l’interface avec nos applications. Nous allons ensuite configurer Nginx pour inverser le proxy sur uWSGI, nous donnant ainsi accès à ses fonctionnalités de sécurité et de performances pour servir nos applications.

Prérequis et objectifs

Afin de compléter ce guide, vous devez disposer d’une nouvelle instance de serveur Ubuntu 14.04 avec un utilisateur non root avec les privilèges + sudo + configurés. Vous pouvez apprendre à configurer ceci en parcourant notre initial guide de configuration du serveur.

Nous installerons Django dans deux environnements virtuels différents. Cela permettra à vos projets et à leurs exigences d’être traités séparément. Nous allons créer deux exemples de projets afin de pouvoir suivre les étapes dans un environnement multi-projets.

Une fois que nous avons nos applications, nous allons installer et configurer le serveur d’application uWSGI. Cela servira d’interface avec nos applications, qui traduira les demandes des clients utilisant HTTP en appels Python que notre application peut traiter. Nous installerons ensuite Nginx devant uWSGI pour tirer parti de ses mécanismes de traitement des connexions hautes performances et de ses fonctionnalités de sécurité faciles à mettre en œuvre.

Commençons.

Installer et configurer VirtualEnv et VirtualEnvWrapper

Nous installerons nos projets Django dans leurs propres environnements virtuels pour isoler les exigences de chacun. Pour ce faire, nous allons installer + virtualenv +, qui peut créer des environnements virtuels Python, et + virtualenvwrapper +, qui ajoute des améliorations en termes de convivialité au flux de travail + virtualenv +.

Nous allons installer ces deux composants en utilisant + pip +, le gestionnaire de paquets Python. Ceci peut être acquis à partir des dépôts Ubuntu:

sudo apt-get update
sudo apt-get install python-pip

Dans ce guide, nous utilisons Python version 2. Si votre code utilise Python 3, vous pouvez installer le package + python3-pip +. Vous devrez ensuite substituer les commandes + pip + de ce guide par la commande + pip3 + lorsque vous travaillez en dehors d’un environnement virtuel.

Maintenant que + pip + est installé, nous pouvons installer + virtualenv + et + virtualenvwrapper + globalement en tapant:

sudo pip install virtualenv virtualenvwrapper

Avec ces composants installés, nous pouvons maintenant configurer notre shell avec les informations nécessaires pour fonctionner avec le script + virtualenvwrapper +. Nos environnements virtuels seront tous placés dans un répertoire de notre dossier de départ appelé + Env + pour un accès facile. Ceci est configuré via une variable d’environnement appelée + WORKON_HOME +. Nous pouvons l’ajouter à notre script d’initialisation du shell et pouvons générer le script wrapper de l’environnement virtuel.

Si vous utilisez Python 3 et la commande + pip3 +, vous devrez également ajouter une ligne supplémentaire à votre script d’initialisation du shell:

echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc

Quelle que soit la version de Python que vous utilisez, vous devez exécuter les commandes suivantes:

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

Maintenant, sourcez votre script d’initialisation du shell pour pouvoir utiliser cette fonctionnalité dans votre session actuelle:

source ~/.bashrc

Vous devriez maintenant avoir un répertoire appelé + Env + dans votre dossier personnel qui contiendra les informations sur l’environnement virtuel.

Créer des projets Django

Maintenant que nous avons nos outils d’environnement virtuel, nous allons créer deux environnements virtuels, installer Django dans chacun d’eux et démarrer deux projets.

Créer le premier projet

Nous pouvons créer facilement un environnement virtuel en utilisant certaines commandes que le script + virtualenvwrapper + met à notre disposition.

Créez votre premier environnement virtuel avec le nom de votre premier site ou projet en tapant:

mkvirtualenv

Cela créera un environnement virtuel, y installera Python et + pip +, et activera l’environnement. Votre invite changera pour indiquer que vous opérez maintenant dans votre nouvel environnement virtuel. Cela ressemblera à quelque chose comme ceci: + () @: ~ $ +. La valeur entre parenthèses est le nom de votre environnement virtuel. Tous les logiciels installés via + pip + seront désormais installés dans l’environnement virtuel plutôt que sur le système global. Cela nous permet d’isoler nos packages projet par projet.

Notre première étape sera d’installer Django lui-même. Nous pouvons utiliser + pip pour cela sans` + sudo` puisque nous l’installons localement dans notre environnement virtuel:

pip install django

Avec Django installé, nous pouvons créer notre premier exemple de projet en tapant:

cd ~
django-admin.py startproject

Cela créera un répertoire appelé «++» dans votre répertoire personnel. Il contient un script de gestion permettant de gérer divers aspects du projet et un autre répertoire du même nom contenant le code du projet.

Déplacez-vous dans le répertoire de premier niveau afin que nous puissions commencer à définir les exigences minimales pour notre projet exemple.

cd ~/

Commencez par migrer la base de données pour initialiser la base de données SQLite que notre projet utilisera. Vous pouvez configurer une base de données alternative pour votre application si vous le souhaitez, mais cela sort du cadre de ce guide:

./manage.py migrate

Vous devriez maintenant avoir un fichier de base de données appelé + db.sqlite3 + dans votre répertoire de projet. Maintenant, nous pouvons créer un utilisateur administratif en tapant:

./manage.py createsuperuser

Vous devrez sélectionner un nom d’utilisateur, donner une adresse électronique à un contact, puis sélectionner et confirmer un mot de passe.

Ensuite, ouvrez le fichier de paramètres du projet avec votre éditeur de texte:

nano /settings.py

Comme nous allons configurer Nginx pour servir notre site, nous devons configurer un répertoire qui contiendra les actifs statiques de notre site. Cela permettra à Nginx de les servir directement, ce qui aura un impact positif sur les performances. Nous dirons à Django de les placer dans un répertoire appelé + static + dans le répertoire de base de notre projet. Ajoutez cette ligne au bas du fichier pour configurer ce comportement:

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

Enregistrez et fermez le fichier lorsque vous avez terminé. Maintenant, collectez les éléments statiques de notre site et placez-les dans ce répertoire en tapant:

./manage.py collectstatic

Vous pouvez taper «oui» pour confirmer l’action et collecter le contenu statique. Il y aura un nouveau répertoire appelé + static + dans le répertoire de votre projet.

Après tout cela, nous pouvons tester notre projet en démarrant temporairement le serveur de développement. Type:

./manage.py runserver 0.0.0.0:8080

Cela démarrera le serveur de développement sur le port + 8080 +. Accédez au nom de domaine ou à l’adresse IP de votre serveur, suivi de «+ 8080 +» dans votre navigateur:

http://:8080

Vous devriez voir une page qui ressemble à ceci:

image: https: //assets.digitalocean.com/articles/django_uwsgi_nginx_1404/sample_site.png [exemple de site Django]

Ajoutez + / admin + à la fin de l’URL dans la barre d’adresse de votre navigateur et vous serez redirigé vers la page de connexion de l’administrateur:

image: https: //assets.digitalocean.com/articles/django_uwsgi_nginx_1404/admin_login.png [Connexion à l’administrateur Django]

À l’aide des informations de connexion administratives que vous avez sélectionnées à l’aide de la commande + createuperuser +, connectez-vous au serveur. Vous aurez alors accès à l’interface d’administration:

image: https: //assets.digitalocean.com/articles/django_uwsgi_nginx_1404/admin_interface.png [Interface d’administration Django]

Après avoir testé cette fonctionnalité, arrêtez le serveur de développement en tapant CTRL-C dans votre terminal. Nous pouvons maintenant passer à notre deuxième projet.

Créer le deuxième projet

Le deuxième projet sera créé exactement de la même manière que le premier. Nous allons abréger l’explication dans cette section, en vous rendant compte de la façon dont vous l’avez déjà réalisée.

Revenez dans votre répertoire personnel et créez un deuxième environnement virtuel pour votre nouveau projet. Installez Django dans ce nouvel environnement une fois qu’il est activé:

cd ~
mkvirtualenv
pip install django

Le nouvel environnement sera créé _ et_ remplacé par, laissant votre environnement virtuel précédent. Cette instance de Django est entièrement séparée de l’autre que vous avez configurée. Cela vous permet de les gérer indépendamment et de les personnaliser si nécessaire.

Créez le deuxième projet et accédez au répertoire du projet:

django-admin.py startproject
cd ~/

Initialisez la base de données et créez un utilisateur administratif:

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

Ouvrez le fichier de paramètres:

nano /settings.py

Ajoutez l’emplacement des fichiers statiques, comme vous l’avez fait dans le projet précédent:

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

Enregistrez et fermez le fichier. Maintenant, collectez les éléments statiques dans ce répertoire en tapant:

./manage.py collectstatic

Enfin, démarrez le serveur de développement pour tester le site:

./manage.py runserver 0.0.0.0:8080

Vous devriez vérifier le site habituel à:

http://:8080

Connectez-vous également au site d’administration:

http://:8080/admin

Lorsque vous avez confirmé que tout fonctionne comme prévu, tapez CTRL-C dans votre terminal pour arrêter le serveur de développement.

Sauvegarde de l’environnement virtuel

Puisque nous en avons terminé avec la partie Django du guide, nous pouvons désactiver notre deuxième environnement virtuel:

deactivate

Si vous avez à nouveau besoin de travailler sur l’un de vos sites Django, réactivez leurs environnements respectifs. Vous pouvez le faire en utilisant la commande + workon +:

workon

Or:

workon

Encore une fois, désactivez-le lorsque vous avez fini de travailler sur vos sites:

deactivate

Configuration du serveur d’applications uWSGI

Maintenant que deux projets Django sont configurés et prêts à fonctionner, nous pouvons configurer uWSGI. uWSGI est un serveur d’applications pouvant communiquer avec des applications via une interface standard appelée WSGI. Pour en savoir plus à ce sujet, lisez https://www.digitalocean.com/community/tutorials/how-to-set-up-uwsgi-and-nginx-to-serve-python-apps-on-ubuntu-14-04 # définitions-et-concepts [cette section] de notre guide sur la configuration de uWSGI et Nginx sur Ubuntu 14.04.

Installer uWSGI

Contrairement au guide cité ci-dessus, dans ce tutoriel, nous allons installer uWSGI globalement. Cela créera moins de friction dans la gestion de plusieurs projets Django. Avant de pouvoir installer uWSGI, nous avons besoin des fichiers de développement Python sur lesquels le logiciel repose. Nous pouvons l’installer directement à partir des dépôts d’Ubuntu:

sudo apt-get install python-dev

Maintenant que les fichiers de développement sont disponibles, nous pouvons installer uWSGI globalement via + pip + en tapant:

sudo pip install uwsgi

Nous pouvons rapidement tester ce serveur d’applications en lui transmettant les informations d’un de nos sites. Par exemple, nous pouvons lui dire de servir notre premier projet en tapant:

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

Ici, nous avons dit à uWSGI d’utiliser notre environnement virtuel situé dans notre répertoire + ~ / / Env +, de passer dans le répertoire de notre projet et d’utiliser le fichier + wsgi.py + stocké dans notre répertoire ++ intérieur pour servir le fichier. Pour notre démonstration, nous lui avons dit de servir HTTP sur le port + 8080 +. Si vous accédez au nom de domaine ou à l’adresse IP du serveur dans votre navigateur, suivi de «: 8080 +», vous verrez votre site à nouveau (les éléments statiques de l’interface ` / admin +` ne fonctionnent pas encore). Lorsque vous avez terminé de tester cette fonctionnalité, tapez CTRL-C dans le terminal.

Création de fichiers de configuration

Exécuter uWSGI à partir de la ligne de commande est utile pour les tests, mais pas particulièrement pour un déploiement réel. Au lieu de cela, nous exécuterons uWSGI en «mode Emperor», ce qui permet à un processus maître de gérer des applications séparées automatiquement à partir d’un ensemble de fichiers de configuration.

Créez un répertoire qui contiendra vos fichiers de configuration. Comme il s’agit d’un processus global, nous allons créer un répertoire appelé + / etc / uwsgi / sites pour stocker vos fichiers de configuration. Déplacez-vous dans le répertoire après l’avoir créé:

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

Dans ce répertoire, nous placerons nos fichiers de configuration. Nous avons besoin d’un fichier de configuration pour chacun des projets que nous servons. Le processus uWSGI peut prendre des fichiers de configuration dans divers formats, mais nous utiliserons les fichiers + .ini + en raison de leur simplicité.

Créez un fichier pour votre premier projet et ouvrez-le dans votre éditeur de texte:

sudo nano .ini

A l’intérieur, nous devons commencer par l’en-tête de section + [uwsgi] +. Toutes nos informations iront sous cet en-tête. Nous allons également utiliser des variables pour rendre notre fichier de configuration plus réutilisable. Après l’en-tête, définissez une variable appelée + project + avec le nom de votre premier projet. Ajoutez une variable appelée + base + avec le chemin du répertoire de base de votre utilisateur:

[uwsgi]
project =
base = /home/

Ensuite, nous devons configurer uWSGI pour qu’il gère notre projet correctement. Nous devons passer au répertoire du projet racine en définissant l’option + chdir +. Nous pouvons combiner les paramètres de répertoire de base et de nom de projet que nous avons définis précédemment en utilisant la syntaxe +% () +. Ceci sera remplacé par la valeur de la variable lors de la lecture de la configuration.

De manière similaire, nous indiquerons l’environnement virtuel de notre projet. En définissant le module, nous pouvons indiquer exactement comment s’interfacer avec notre projet (en important l’application appelée depuis le fichier + wsgi.py + dans le répertoire de notre projet). La configuration de ces éléments ressemblera à ceci:

[uwsgi]
project =
base = /home/

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

Nous voulons créer un processus maître avec 5 ouvriers. Nous pouvons le faire en ajoutant ceci:

[uwsgi]
project =
base = /home/

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

master = true
processes = 5

Ensuite, nous devons spécifier comment uWSGI doit écouter les connexions. Dans notre test d’uWSGI, nous avons utilisé HTTP et un port réseau. Cependant, puisque nous allons utiliser Nginx en tant que proxy inverse, nous avons de meilleures options.

Au lieu d’utiliser un port réseau, étant donné que tous les composants fonctionnent sur un seul serveur, nous pouvons utiliser un socket Unix. Ceci est plus sécurisé et offre de meilleures performances. Ce socket n’utilisera pas HTTP, mais implémentera le protocole + uwsgi + de uWSGI, qui est un protocole binaire rapide conçu pour la communication avec d’autres serveurs. Nginx peut utiliser un proxy natif en utilisant le protocole + uwsgi +, il s’agit donc de notre meilleur choix.

Nous allons également modifier les autorisations du socket car nous allons donner un accès en écriture au serveur Web. Nous allons paramétrer l’option + vacuum + pour que le fichier de socket soit automatiquement nettoyé à l’arrêt du service:

[uwsgi]
project =
base = /home/

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

master = true
processes = 5

socket = %(base)/%(project)/%(project).sock
chmod-socket = 664
vacuum = true

Avec cela, la configuration de notre premier projet uWSGI est terminée. Enregistrez et fermez le fichier.

L’avantage de configurer le fichier à l’aide de variables est qu’il est extrêmement simple à réutiliser. Copiez le premier fichier de configuration de votre projet à utiliser comme base pour votre deuxième fichier de configuration:

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

Ouvrez le deuxième fichier de configuration avec votre éditeur de texte:

sudo nano /etc/uwsgi/sites/.ini

Nous n’avons besoin de changer qu’une seule valeur dans ce fichier pour que cela fonctionne pour notre deuxième projet. Modifiez la variable + projet + avec le nom que vous avez utilisé pour votre deuxième projet:

[uwsgi]
project =
base = /home/

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

master = true
processes = 5

socket = %(base)/%(project)/%(project).sock
chmod-socket = 664
vacuum = true

Enregistrez et fermez le fichier lorsque vous avez terminé. Votre deuxième projet devrait être prêt à partir maintenant.

Créer un script de démarrage pour uWSGI

Nous avons maintenant les fichiers de configuration dont nous avons besoin pour desservir nos projets Django, mais nous n’avons toujours pas automatisé le processus. Ensuite, nous allons créer un script Upstart pour démarrer automatiquement uWSGI au démarrage.

Nous allons créer un script Upstart dans le répertoire + / etc / init +, où ces fichiers sont vérifiés:

sudo nano /etc/init/uwsgi.conf

Commencez par définir une description de votre service uWSGI et d’indiquer les niveaux d’exécution où il doit s’exécuter automatiquement. Nous allons définir les nôtres pour les niveaux d’exécution 2, 3, 4 et 5, qui sont les niveaux d’exécution classiques pour plusieurs utilisateurs:

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

Ensuite, nous devons définir le nom d’utilisateur et le groupe sous lesquels le processus sera exécuté. Nous allons exécuter le processus sous notre propre nom d’utilisateur puisque nous possédons tous les fichiers. Pour le groupe, nous devons le définir sur le groupe + www-data sous lequel Nginx sera exécuté. Nos paramètres de socket à partir du fichier de configuration uWSGI doivent ensuite permettre au serveur Web d’écrire dans le socket. Changez le nom d’utilisateur ci-dessous pour qu’il corresponde à votre nom d’utilisateur sur le serveur:

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

setuid
setgid www-data

Enfin, nous devons spécifier la commande à exécuter. Nous devons démarrer uWSGI en mode Emperor et passer dans le répertoire où nous avons stocké nos fichiers de configuration. uWSGI lira les fichiers et servira chacun de nos projets:

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

setuid
setgid www-data

exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites

Lorsque vous avez terminé, enregistrez et fermez le fichier. Nous ne lancerons pas encore uWSGI car nous ne disposerons pas du groupe + www-data + avant l’installation de Nginx.

Installer et configurer Nginx en tant que proxy inverse

Avec uWSGI configuré et prêt à fonctionner, nous pouvons maintenant installer et configurer Nginx en tant que proxy inverse. Ceci peut être téléchargé à partir des dépôts par défaut d’Ubuntu:

sudo apt-get install nginx

Une fois que Nginx est installé, vous pouvez créer un fichier de configuration de bloc de serveur pour chacun de nos projets. Commencez par le premier projet en créant un fichier de configuration de bloc de serveur:

sudo nano /etc/nginx/sites-available/

À l’intérieur, nous pouvons démarrer notre bloc de serveurs en indiquant le numéro de port et le nom de domaine où notre premier projet devrait être accessible. Nous supposerons que vous avez un nom de domaine pour chacun:

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

Ensuite, nous pouvons dire à Nginx de ne pas s’inquiéter si elle ne peut pas trouver un favicon. Nous le signalerons également à l’emplacement de notre répertoire de fichiers statiques où nous avons collecté les éléments statiques de notre site:

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

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

Après cela, nous pouvons utiliser la directive + uwsgi_pass + pour transmettre le trafic à notre fichier de socket. Le fichier de socket que nous avons configuré s’appelait + .sock + et il se trouvait dans le répertoire de notre projet. Nous allons utiliser la directive + include + pour inclure les paramètres + uwsgi + nécessaires pour gérer la connexion:

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

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

   location / {
       include         uwsgi_params;
       uwsgi_pass      unix:/home///.sock;
   }
}

C’est en fait toute la configuration dont nous avons besoin. Enregistrez et fermez le fichier lorsque vous avez terminé.

Nous nous en servirons comme base pour le fichier de configuration Nginx de notre deuxième projet. Recopiez-le maintenant:

sudo cp /etc/nginx/sites-available/ /etc/nginx/sites-available/

Ouvrez le nouveau fichier dans votre éditeur de texte:

sudo nano /etc/nginx/sites-available/

Ici, vous devrez changer toute référence à ` avec une référence à `. Vous devrez également modifier le + nom_serveur + pour que votre deuxième projet réponde à un nom de domaine différent. Lorsque vous avez terminé, cela ressemblera à quelque chose comme ceci:

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

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

   location / {
       include         uwsgi_params;
       uwsgi_pass      unix:/home///.sock;
   }
}

Enregistrez et fermez le fichier lorsque vous avez terminé.

Ensuite, liez vos deux nouveaux fichiers de configuration au répertoire + sites + activé + de Nginx pour les activer:

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled

Vérifiez la syntaxe de configuration en tapant:

sudo service nginx configtest

Si aucune erreur de syntaxe n’est détectée, vous pouvez redémarrer votre service Nginx pour charger la nouvelle configuration:

sudo service nginx restart

Si vous vous en souvenez, nous n’avons jamais démarré le serveur uWSGI. Faites-le maintenant en tapant:

sudo service uwsgi start

Vous devriez maintenant pouvoir atteindre vos deux projets en accédant à leurs noms de domaine respectifs. Les interfaces publique et administrative doivent fonctionner comme prévu.

Conclusion

Dans ce guide, nous avons configuré deux projets Django, chacun dans son propre environnement virtuel. Nous avons configuré uWSGI pour desservir chaque projet indépendamment à l’aide de l’environnement virtuel configuré pour chacun. Ensuite, nous avons configuré Nginx pour qu’il agisse en tant que proxy inverse pour gérer les connexions client et servir le projet approprié en fonction de la demande du client.

Django facilite la création de projets et d’applications en fournissant de nombreux éléments communs, vous permettant de vous concentrer sur des éléments uniques. En exploitant la chaîne d’outils générale décrite dans cet article, vous pouvez facilement desservir les applications que vous créez à partir d’un seul serveur.