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 sometimes 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
development tools on your server roll debs
).
Note
For development environment Pythonz is a nice tool to compile (and manage) many versions of python.
If you want deploy your server by hand just download and compile python.
If you are into automatic deployment (and you should be)
Assumptions about the system¶
I’ll assume that you will configure your system in following way:
- Django application will be using
www-client
user - Code will be inside
/home/www-client/repo
- There will be a django generated uwsgi file in
/home/www-client/repo/webapp.uwsgi
- Virtualenv will be in
/home/www-client/repo/venv
.
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.
You can configure uwsgi
using a variety of ways, most of which are better
than using a command line arguments :). For example you can create an ini file
named uwsgi.ini
:
module=webapp.wsgi
pythonpath=/home/www-client/webapp
http=8000
And then start uwsgi using: uwsgi --ini uwsgi.ini
.
Use systemd to launch your applicaiton¶
Now use systemd to launch the application.
Systemd is a very nice init system that is becoming a standard in most recent distributions (it’s even on Debian stable).
If your distribution has no systemd you can use supervisord (which is even on debian oldstable), tutorial to deploy django with it is here.
So create /home/webapp/uwsgi.ini
file with following contents:
module=webapp.wsgi
http=8000
pythonpath=/home/www-client/repo
Create a webapp.service
file and put it in /etc/systemd/system/
,
file should have following contents:
[Unit]
Description=Description
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
# What process to start
ExecStart=/home/www-client/venv/bin/uwsgi --ini /home/www-client/uwsgi.ini
# What user chown to
User=www-client
# Working directory
WorkingDirectory=/home/www-client/webapp
Restart=always
# Kill by SIGQUIT signal --- this is what asks wsgi to die nicely
KillSignal=SIGQUIT
# Notify type, in this type uwsgi will inform systemd that it is ready to handle requests
Type=notify
StandardError=syslog
NotifyAccess=all
Then:
sudo systemctl --system enable webapp
sudo systemctl start webapp
Now you should have a working uwsgi configuration, which is reachable at localhost:8000
.
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
In this part we will put uwsgi
behind nginx
server.
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 /etc/nginx/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.ini
file with something like:
And also create /home/www-client/sock/
.
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¶
Now we’ll update settings so static media is served by nginx.
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.