Browse files

more work on servers docs

  • Loading branch information...
1 parent 07aeb22 commit 76e0996c4f5fa5b65c312f4ea03422b7ca5fc647 @ipmb ipmb committed Apr 13, 2009
Showing with 75 additions and 6 deletions.
  1. +42 −5 deployment/servers.txt
  2. +1 −1 examples/apache.conf
  3. +14 −0 examples/django.wsgi
  4. +18 −0 examples/nginx_ssl.conf
@@ -1,15 +1,14 @@
.. _deployment-servers:
-.. index:: Apache, mod_wsgi, Nginx, PostgreSQL, Linux
.. note:: Deployment arcitectures vary widely depending on the needs and traffic of the site. The setup described below works best for us in most instances.
We serve Django on Linux with a PostgreSQL database backend via Apache and `mod_wsgi <>`__ from behind an `Nginx <>`__ instance acting as a frontend proxy.
+.. index:: Nginx
@@ -22,10 +21,48 @@ Nginx
The first block tells Nginx where to find the server hosting our Django site. The second block redirects any request coming in on ```` to ```` so each resource has only one URL that will access it. The final block is the one that does all the work. It tells Nginx to check if a file matching the request exists in ``/var/www/``. If it does, it serves that file, if it doesn't, it proxies the request to the Django site.
+.. index::
+ pair: Nginx; SSL
+Another benefit to running a frontend server is lightweight SSL proxying. Rather than having two Django instances running for SSL and non-SSL access, we can have Nginx act as the gatekeeper redirecting all requests back to a single non-SSL Apache instance listening on the ``localhost``. Here's what that would look like:
+.. literalinclude:: /examples/nginx_ssl.conf
+ :language: nginx
+You can include this code at the bottom of your non-SSL configuration file.
+.. tip:: For SSL-aware Django sites like `Satchmo <>`_, you'll need to "trick" the site into thinking incoming requests are coming in via SSL, but this is simple enough to do with `a small addition to the WSGI script <>`_ we discuss below.
+.. index:: Apache
+ pair: Apache; mod_wsgi
+ pair: Apache; Worker MPM
+ pair: Apache; Listen
-We run the Apache2 Worker MPM with `mod_wsgi <>`__ in daemon mode. A typical Apache configuration for an individual site looks like this:
+We run the Apache2 Worker MPM with `mod_wsgi <>`__ in daemon mode. The default settings for the MPM Worker module should be sufficient for most environments although those with a shortage of RAM may want to look into reducing the number of servers spawned. Since Nginx will be listening for HTTP(S) requests, you'll need to bind Apache to a different port. While you're at it, you can tell it to only respond to the ``localhost``. To do so, you'll want to edit the `Listen directive <>`_
+.. sourcecode:: apache
+ Listen
+.. index:: mod_wsgi
+With Apache up and running, you'll need an Apache configuration and WSGI script for each site. A typical Apache configuration for an individual site looks like this:
.. literalinclude:: /examples/apache.conf
- :language: apache
+ :language: apache
+It links to the WSGI script within the project directory. The script is just a few lines of Python to properly setup our environment.
+.. literalinclude:: /examples/django.wsgi
+ :language: python
+.. index::
+ pair: mod_wsgi; maximum-requests
+In a perfect world, your app would never leak memory and you can leave out the ``maximum-requests`` directive. In our experience, setting this to a high number is nice to keep Apache's memory usage in check.
@@ -3,7 +3,7 @@
ErrorLog /var/log/apache2/
- WSGIDaemonProcess domain user=www-data group=www-data processes=1 threads=10 maximum-requests=10000
+ WSGIDaemonProcess domain display-name=%{GROUP} maximum-requests=10000
WSGIProcessGroup domain
WSGIScriptAlias / /opt/webapps/
@@ -0,0 +1,14 @@
+import os, sys
+import site
+# put virtualenv on pythonpath
+# redirect print statements to apache log
+sys.stdout = sys.stderr
+os.environ['DJANGO_SETTINGS_MODULE'] = 'domain.settings'
+import django.core.handlers.wsgi
+application = django.core.handlers.wsgi.WSGIHandler()
@@ -0,0 +1,18 @@
+server {
+ listen; #replace with your own ip address
+ server_name;
+ root /var/www/;
+ access_log /var/log/nginx/;
+ ssl on;
+ ssl_certificate /etc/nginx/ssl/certs/;
+ ssl_certificate_key /etc/nginx/ssl/private/;
+ ssl_prefer_server_ciphers on;
+ proxy_set_header X-Forwarded-Protocol https;
+ if (!-f $request_filename) {
+ proxy_pass http://django;
+ }

0 comments on commit 76e0996

Please sign in to comment.