How to deploy django application on debian server (UWSGI version)¶
Install proper version of python¶
On debian I’d discourage using system
python for deployment — mostly
becaluse they tend to upgrade minor python versions without notice,
which breaks C ABI
in installed virtualenvs.
So either roll your own deb
files that install pythons somewhere in
/usr/local
or compile python on server (if you frown on having
developement tools on your server roll debs
).
Pythonz is a nice tool to compile (and manage) many versions of python.
Install proper version of virtualenv¶
Note
This is more-or less irrevelant as Python (from version 3.4 onwards) has it’s own built-in virtualenv tool, so if you use non-system one it’ll have its own virtualenv.
Debian comes with ancient python/virtualenv version, and (at least on
testing
) it often breaks this install. If you install virtualenv locally
it’ll be much more stable.
To install virtualenv locally just download virtualenv, unpack package
and use virtualenv.py
.
This hsa the added benefit that you can have two versions of virtualenv one for python2 and one for python3.
Install your application into virtualenv¶
You know how to do that don’t you?
Now you can tests whether your setup is correct, just run
./manage.py runserver
and see if you can connect to your application.
Install uwsgi into your virtualenv¶
Install uwsgi
into your virtualenv from pip
. Now you can run
your application using uwsgi:
uwsgi --http :8000 --module webapp.wsgi
I strongly discourage you from using uwsgi bundled with system.
Use supervisord to launch your applicaiton¶
You’ll need to run your application on system start, simplest way is to
use supervisord
(you can install it via aptitude).
First create a script that will:
- Source virtualenv
- cd to your app directory
- run uwsgi.
Something along the lines:
#!/bin/bash
export HOME=/home/user
source $HOME/venv/bin/activate
cd $HOME/webapp
uwsgi --socket :8000 --module webapp.wsgi
exit $?
Notice that --http
turned into --socket
. Now uwsgi will
speak uwsgi
protocol (which should be faster than http).
Then add configuration to supervisord. All services are defined as *conf
files
(in ini
format) inside /etc/supervisor/conf.d
.
Create file containing something like:
[program:webapp]
command=/home/webapp/webapp.sh
autostart=true
autorestart=true
stderr_logfile=/var/log/webapp.err.log
stdout_logfile=/var/log/webapp.out.log
user=webapp
For all configuration options see the documentation.
Now after calling: service supervisor restart
your django application
should be running.
Connect uwsgi
and nginx
¶
Note
This part is more or less ripoff from: http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html
Add following sections to nginx configuration:
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8000; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 80;
# the domain name it will serve for
server_name .example.com; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /path/to/your/mysite/uwsgi_params; # the uwsgi_params file you installed
}
}
Now you should see something on your server port 80
. To finalize our setup
we need to create static and media directories.
Connect ngingx and uwsgi via linux file sockets¶
Because of many (peformance, safety) reasons it is better to connect nginx with uwsgi via linux domain sockets.
First replace uwsgi
call with something like that:
uwsgi --module webapp.wsgi --socket $HOME/sock/webapp.sock --chown-socket=webapp-user:www-data --chmod-socket=660
This does the following: creates a socket in $HOME/sock/webapp.sock
,
sets its group ownership to www-data
(which is user/group used by
both nginx
and apache
on default debian configuration).
Note
Linux file sockets use normal file permissions, so nginx
has to
have read-write access to it.
Then replace:
upstream django {
server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
with:
upstream django {
server unix:///path/to/your/mysite/webapp.sock; # for a file socket
}
Update media and static root¶
Update settings py¶
You’ll need to update STATIC_ROOT
, STATIC_URL
,
MEDIA_ROOT
, MEDIA_URL
settings of youe app.
Something along the lines:
MEDIA_ROOT = '/var/drigan-media'
MEDIA_URL = '/media/'
STATIC_ROOT = '/var/drigan-static'
STATIC_URL = '/static/'
Update nginx¶
location /media {
alias /path/to/your/mysite/media; # your Django project's media files - amend as required
}
location /static {
alias /path/to/your/mysite/static; # your Django project's static files - amend as required
}
Tweak uwsgi so it scales¶
You might want tweak uwsgi
so it launches more processes/workers, but
this well outside scope of this tutorial.