82 lines
4.0 KiB
ReStructuredText
82 lines
4.0 KiB
ReStructuredText
|
*************
|
||
|
Gunicorn
|
||
|
*************
|
||
|
|
||
|
Nous allons utiliser ``gunicorn`` comme serveur d'applications, le serveur fourni par django n'étant pas fait pour être utilisé en production.
|
||
|
|
||
|
Gunicorn a déjà été installé lors de la préparation de l'environnement. De même que ``setproctitle``, qui est nécessaire pour donner le nom de l'application aux processus python lancés par gunicorn.
|
||
|
|
||
|
Nous pouvons donc directement tester s'il fonctionne:
|
||
|
|
||
|
.. code-block:: shell
|
||
|
|
||
|
(gwift)gwift@gwift:~$ gunicorn gwift.wsgi:application --bind esever_name.com:8000
|
||
|
|
||
|
Et en se rendant sur server_name.com:8000/admin, on obtient la même chose qu'avec le serveur de django:
|
||
|
|
||
|
.. image:: production/admin_without_static.png
|
||
|
:align: center
|
||
|
|
||
|
Nous allons maintenant créer un fichier qui se chargera de lancer gunicorn correctement, que l'on sauve dans ``/webapps/gwift/gwift/bin/gunicorn_start``:
|
||
|
|
||
|
.. code-block:: shell
|
||
|
|
||
|
#!/bin/bash
|
||
|
|
||
|
# Define settings for gunicorn
|
||
|
NAME="gwift" # Name of the application
|
||
|
DJANGODIR=/webapps/gwift/gwift/gwift # Django project directory
|
||
|
SOCKFILE=/webapps/gwift/gwift/run/gunicorn.sock # we will communicte using this unix socket
|
||
|
USER=gwift # the user to run as
|
||
|
GROUP=webapps # the group to run as
|
||
|
NUM_WORKERS=3 # how many worker processes should Gunicorn spawn
|
||
|
DJANGO_SETTINGS_MODULE=gwift.settings # which settings file should Django use
|
||
|
DJANGO_WSGI_MODULE=gwift.wsgi # WSGI module name
|
||
|
|
||
|
echo "Starting $NAME as `whoami`"
|
||
|
|
||
|
# Activate the virtual environment
|
||
|
source /webapps/gwift/.virtualenvs/gwift/bin/activate
|
||
|
cd $DJANGODIR
|
||
|
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
|
||
|
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
|
||
|
|
||
|
# Create the run directory if it doesn't exist
|
||
|
RUNDIR=$(dirname $SOCKFILE)
|
||
|
test -d $RUNDIR || mkdir -p $RUNDIR
|
||
|
|
||
|
# Start your Django Unicorn
|
||
|
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
|
||
|
exec gunicorn ${DJANGO_WSGI_MODULE}:application \
|
||
|
--name $NAME \
|
||
|
--workers $NUM_WORKERS \
|
||
|
--user=$USER --group=$GROUP \
|
||
|
--bind=unix:$SOCKFILE \
|
||
|
--log-level=debug \
|
||
|
--log-file=-
|
||
|
|
||
|
Explications:
|
||
|
|
||
|
* NUM_WORKERS : gunicorn lance autant de worker que ce nombre. Un worker représente l'équivallant d'une instance de django et ne peut traiter qu'une requête à la fois. Traditionnellement, on créé autant de worker que le double du nombre de processeurs plus un.
|
||
|
* SOCKFILE : on configure gunicorn pour communiquer via un socket unix, ce qui est plus efficace de le faire par tcp/ip
|
||
|
|
||
|
Le script se charge donc de définir les options de configuration de gunicorn, de lancer l'environnement virtuel et ensuite gunicorn.
|
||
|
|
||
|
On peut le tester avec la commande suivante (hors environnement virtuel):
|
||
|
|
||
|
.. code-block:: shell
|
||
|
|
||
|
gwift@gwift:~$ source /webapps/gwift/gwift/bin/gunicorn_start
|
||
|
|
||
|
Et avec un petit ``ps`` dans un autre shell:
|
||
|
|
||
|
.. code-block:: shell
|
||
|
|
||
|
gwift@gwift:~$ ps -u gwift -F
|
||
|
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
|
||
|
gwift 31983 15685 0 18319 15084 1 Apr29 ? 00:00:01 gunicorn: master [gwift]
|
||
|
gwift 31992 31983 0 35636 29312 1 Apr29 ? 00:00:00 gunicorn: worker [gwift]
|
||
|
gwift 31993 31983 0 35634 29280 2 Apr29 ? 00:00:00 gunicorn: worker [gwift]
|
||
|
gwift 31994 31983 0 35618 29228 0 Apr29 ? 00:00:00 gunicorn: worker [gwift]
|
||
|
|
||
|
On voit donc bien qu'il y a un maître et trois workers.
|