A Django setup using Nginx and Gunicorn
The conventional way to run Django in production these days is usingApache2 and mod_wsgi. While there’s nothing wrong with that approach,I prefer Nginx. I also like to be able to control Django server separately from the web server.
There are several production-ready servers for Django. The best seem to be Gunicorn and uWSGI, and Gunicorn seems the best supported and most active project.
When running Django server separately from the web server, we need a way to start, stop and restart the Django server. A popular way for doing it in Django world is Supervisor, altough, for Ubuntu users, Upstart might be less hassle.
You probably already have a Django project you want to deploy, but for completenes’ sake, the steps here will use an empty toy “Hello World” Django project:
Preparation
First things first – you are using virtualenv, right? If not, you should.
virtualenv --no-site-packages test
cd test
source bin/activate
pip install gunicorn django
django-admin.py startproject hello
cd hello
# to test the base setup works
python manage.py runserver 0.0.0.0:8000
Gunicorn
Testing Django with Gunicorn is as simple as:
gunicorn_django -b 0.0.0.0:8000
For production, we might want a bit more options, and we want to make sure the server is executing in the correct environment. The easiest way is to create a shell script to set it all up:
#!/bin/bash
set -e
LOGFILE=/var/log/gunicorn/hello.log
LOGDIR=$(dirname $LOGFILE)
NUM_WORKERS=3
# user/group to run as
USER=your_unix_user
GROUP=your_unix_group
cd /path/to/test/hello
source ../bin/activate
test -d $LOGDIR || mkdir -p $LOGDIR
exec ../bin/gunicorn_django -w $NUM_WORKERS \
--user=$USER --group=$GROUP --log-level=debug \
--log-file=$LOGFILE 2>>$LOGFILE
The number of workers is number of worker processes that will serve requests. You can set it as low as 1 if you’re on a small VPS. A popular formula is 1 + 2 * number_of_cpus on the machine (the logic being, half of the processess will be waiting for I/O, such as database). YMMV.
Don’t forget to mark the script as executable (chmod ug+x script.sh). You can run it from the command line for testing. Note that Gunicorn by default uses 127.0.0.1:8000 address (the same as Django debug server), which is fine if Nginx is on the same machine – you usually don’t want to have it wide open to anyone, and instead let Nginx handle incoming connections.
If you want to run several Django servers on the same machine, just make sure each uses a different port number.
Supervisor
Supervisor has extensive documentation, and this blog post is big already, so I’ll just point you to the official docs. The config file for running our server (/etc/supervisor/cont.d/hello.conf on Debian/Ubuntu) should look like this:
[program:hello]
directory = /path/to/test/hello/
user = your_unix_user
command = /path/to/test/hello/script.sh
stdout_logfile = /path/to/logfile.log
stderr_logfile = /path/to/logfile.log
Test it with supervisorctl {start,status,stop} hello (as root).
Upstart
Ubuntu alternative is Upstart, which has a similar config file (/etc/init/hello.conf). An example:
description "Test Django instance"
start on runlevel [2345]
stop on runlevel [06]
respawn
respawn limit 10 5
exec /path/to/test/hello/script.sh
Test it with service hello {start,status,stop} (as root).
Update 2011-11-14:For completeness of the Upstart setup configuration one has to add a soft link in
/etc/init.d
for a file named hello
to /lib/init/upstart-job
. So the following instruction should be executed after the .conf file has been created in /etc/init: sudo ln -s /lib/init/upstart-job /etc/init.d/hello
Update 2011-11-14: Christophe Meessen found and fixed several errors in the procedures and config files, and also provided info about the extra Upstart configuration I missed. Thanks Christophe!
Nginx
If you don’t have it set up, you should also install Nginx. The install procedure varies from system to system. On Debian and Ubuntu systems, it’s as simple as apt-get install nginx, and other Linux distributions usually have equivalent commands.
Nginx is mostly a drop-in replacement for Apache for serving static files, though there are some things to set up if you need to run PHP code as well.
For our setup, we need Nginx to serve as the reverse proxy for the upstream server(s). To do so, we add a server section to the config file:
server {
listen 80;
server_name example.com;
# no security problem here, since / is alway passed to upstream
root /path/to/test/hello;
# serve directly - analogous for static/staticfiles
location /media/ {
# if asset versioning is used
if ($query_string) {
expires max;
}
}
location /admin/media/ {
# this changes depending on your python version
root /path/to/test/lib/python2.6/site-packages/django/contrib;
}
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://localhost:8000/;
}
# what to serve if upstream is not available or crashes
error_page 500 502 503 504 /media/50x.html;
}
Ubuntu and Debian systems keep Nginx config files in same layout as for Apache, so the above cold be added to /etc/nginx/sites-available/hello(and enabled by symlinking from sites-enabled directory). Use nginx -t for config test and nginx -s reload to reload the configuration.
That’s it
And that’s it. The services are really quite simple to set up once you know what goes where, the setup is flexible and performant, and the server environments are isolated so it’s possible to host many different services with varying requirements on the same machine.
Have improvements on the above or your own helpful tips, or found an error in the post? Share in the comments.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.