Hello everybody,

Do you think uWSGI deserves a place in the official django documentation ?

I think it should because it's easier, safer, faster and more secure
than flup or mod_wsgi. Also, it made my sysadmin life really easy and
that's something cool to share with the community.

In this case, please consider the attached draft
(django/docs/howto/deployment/uwsgi.txt): it's not perfect and
probably not commitable as-is, but I am ready to listen to feedback
and improve it. Otherwise it'll just make another blog post.

What do you think ?

Cheers

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

============================
How to use Django with uWSGI
============================

.. highlight:: bash

uWSGI_ is a fast, self-healing and developer/sysadmin-friendly application
container server coded in pure C. It comes with all the advantages of FastCGI:

* sane, runs in a site-specific process other than the web server
* secure, can run with a site-specific user and group
* fast, uWSGI_ is fastest in most setups

_uWSGI comes with additional advantages:

* it provides a simple Web server,
* it can gracefully restart the process, without loosing any requests unlike
  a fastcgi process restart
* lower memory footprint than flup or mod_wgsi
* provides a safe and fast `cache backend for django
  <http://projects.unbit.it/uwsgi/wiki/CachingFramework>`_

The full list of advantages are on the _uWSGI homepage.

.. _uWSGI: http://projects.unbit.it/uwsgi/

Prerequisite: general concept
=============================

uWSGI_ provides a command to start a project process. The Web server uses the
process through a socket file created by uWSGI_. The system administrator
controls the process using the pid written by uWSGI_ in the pidfile.

If the Web server doesn't serve the application correctly, the system
administrator should ensure that:

* the Web server log file: it should tell if the Web server managed to connect
  to the uWSGI_ process or not
* if the process socket is a file: the Web server process should have
  write permission on the socket file
* if the process socket is a file: uWSGI_ sometimes won't erase the socket
  file on interruption, remove the file and start uWSGI again in that case
* uWSGI_ can start the process on the foreground which will make errors easily
  visible to the system administrator

Prerequisite: uWSGI
===================

`uWSGI wiki<http://projects.unbit.it/uwsgi/wiki/Install>`_ describes several
installation procedures. The simplest way is to run this command::

    # install current stable version
    pip install uwsgi
    # install LTS (long term support)
    pip install http://projects.unbit.it/downloads/uwsgi-lts.tar.gz

Managing the uWSGI server
=========================

uWSGI operates on a client-server model, and in most cases you'll be starting
the uWSGI process on your own. Your Web server (be it Nginx, or otherwise)
only contacts your Django-uWSGI process when the server needs a dynamic page
to be loaded. Because the daemon is already running with the code in memory,
it's able to serve the response very quickly.

A Web server can connect to an uWSGI_ server in one of two ways: It can use
either a Unix domain socket (a "named pipe" on Win32 systems), or it can use a
TCP socket. What you choose is a manner of preference; a TCP socket is usually
easier due to permissions issues.

Starting the server
-------------------

uWSGI is highly configurable and thus there are many ways to start the
process. For example, uwsgi version 0.9.6.8 provides a hundred switches.
This guide demonstrates the most important of them, but does not intent to
substitute the official manual and online documentation.

Starting a process with uWSGI takes an additional python script. The script
can be in the project directory, named 'youruwsgi.py'::

    from django.core.handlers.wsgi import WSGIHandler
    
    # set application for WSGI processing
    application = WSGIHandler()

To communicate with other applications like a Web server, uWSGI_ uses a
socket. You'll need to specify either a :djadminopt:`socket`, a
:djadminopt:`protocol` or both :djadminopt:`host` and :djadminopt:`port`.
Then, when you set up your Web server, you'll just need to point it at the
host/port or socket you specified when starting the FastCGI server.

.. admonition:: Choosing the socket

    The easiest is to set the socket to a high level (>1024) local port like
    127.0.0.1:3000. If the socket is a file, the system administrator must
    ensure that the Web server process has rwx privileges on that file.

To start one uWSGI process to handle requests with your project::

    uwsgi --home=/path/to/your/project --module=youruwsgi \
        --socket=127.0.0.1:3000

uWSGI starts processes that handle requests. This kind of process are called
'worker processes'. Starting 5 worker processes is sufficient to allow
concurrency of requests for development::

    uwsgi --home=/path/to/your/project --module=youruwsgi \
        --socket=127.0.0.1:3000 \
        --processes=5

When uwsgi is run as root, it is possible to make it drop privileges. For
example, to run the uwsgi process with user id 1000 and group id 2000::
 
    uwsgi --home=/path/to/your/project --module=youruwsgi \
        --socket=127.0.0.1:3000 \
        --processes=5 \
        --uid=1000 --gid=2000

uWSGI_ process management is a very nice feature and even a core component of
uwsgi. Process management is done by the "master" process. Unlike worker
processes, the master process does not handle requests. It's only role is to
monitor and manage a worker process pool. It will never be enabled by default
but you should always enable it::
    
    uwsgi --home=/path/to/your/project --module=youruwsgi \
        --socket=127.0.0.1:3000 \
        --processes=5 \
        --uid=1000 --gid=2000 \
        --master --pidfile=/tmp/project-master.pid

One of the features of the master process is that it can kill and respawn
processes that take too long to handle a request. For example, if a process
that has not handled a request after 20 seconds must be killed and replaced::
    
    uwsgi --home=/path/to/your/project --module=youruwsgi \
        --socket=127.0.0.1:3000 \
        --processes=5 \
        --uid=1000 --gid=2000 \
        --master --pidfile=/tmp/project-master.pid \
        --harakiri=20

uWSGI_ can also limit memory used by workers. For example, to limit your
project processes to 128 Megabytes::
    
    uwsgi --home=/path/to/your/project --module=youruwsgi \
        --socket=127.0.0.1:3000 \
        --processes=5 \
        --uid=1000 --gid=2000 \
        --master --pidfile=/tmp/project-master.pid \
        --harakiri=20 \
        --limit-as 128

uWSGI can also ensure worker process freshness. Unlike php-cgi, it is unlikely
that a django uwsgi process would require that. In case of random memory
leaks, limiting the number of requests handled by a worker process before
replacement to 5000::

    uwsgi --home=/path/to/your/project --module=youruwsgi \
        --socket=127.0.0.1:3000 \
        --processes=5 \
        --uid=1000 --gid=2000 \
        --master --pidfile=/tmp/project-master.pid \
        --harakiri=20 \
        --limit-as=128 \
        --max-requests=5000

uWSGI can also run in the background. Running uWSGI in the background makes it
possible for a server process manager like init, supervisor, or else to start
the project. In that case, a path must be specified for uWSGI to write logs::

    uwsgi --home=/path/to/your/project --module=youruwsgi \
        --socket=127.0.0.1:3000 \
        --processes=5 \
        --uid=1000 --gid=2000 \
        --master --pidfile=/tmp/project-master.pid \
        --harakiri=20 \
        --limit-as=128 \
        --max-requests=5000 \
        --daemonize=/var/log/uwsgi/yourproject.log

Stopping the daemon
-------------------

If you have the process running in the foreground, it's easy enough to stop it:
Simply hitting ``Ctrl-C`` will stop and quit the uWSGI server. However, when
you're dealing with background processes, you'll need to resort to the Unix
``kill`` command.

The ``kill`` is used to send a signal to the uWSGI_ master process. The
`uWSGI_ signals are documented online
<http://projects.unbit.it/uwsgi/wiki/uWSGISignals>`_. Example command to
completely stop the uWSGI_ stack::

    kill -INT `cat /tmp/project-master.pid`

Reloading the daemon
--------------------

As mentioned above, the uWSGI_ master process is one of the core component of
the uWSGI_ stack. The signal to brutally reload all the workers and the master
process is SIGTERM. Example command to brutally reload the uWSGI_ processes::

    kill -TERM `cat /tmp/project-master.pid`

Patching the daemon
-------------------

One of the great advantages of uWSGI_ is its ability to gradually restart each
worker without loosing any request. For example, uWSGI_ can be signaled that
worker should reload the code after handling their current request (if any)::

    kill -HUP `cat /tmp/project-master.pid`

Nginx setup
===========

Nginx provides the uwsgi module by default these days. Configuring Nginx to
use an uWSGI server is as simple as setting it up to proxy requests::

    location / { 
        uwsgi_pass 127.0.0.1:3000;
        # in case of a socket file:
        # uwsgi_pass unix:/tmp/yourproject.sock;
    }

Note that default uwsgi parameters should be included somewhere in your Nginx
configuration. For example::

    http {
        include       uwsgi_params;
        # [...] normal nginx configuration here
    }

Cherokee setup
==============

Cherokee is a very fast, flexible and easy to configure Web Server. It
supports the widespread technologies nowadays: FastCGI, SCGI, PHP, CGI, SSI,
TLS and SSL encrypted connections, Virtual hosts, Authentication, on the fly
encoding, Load Balancing, Apache compatible log files, Data Base Balancer,
Reverse HTTP Proxy and much more.

The Cherokee project provides a documentation to `setting up Django`_ with 
Cherokee.

.. _setting up Django: 
http://www.cherokee-project.com/screencasts.html#django_uwsgi

Reply via email to