1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #16360 -- Added WSGI entrypoint to startproject layout, and enabled internal servers (runserver and runfcgi) to use an externally-defined WSGI application. Thanks to Armin Ronacher, Jannis Leidel, Alex Gaynor, ptone, and Jacob Kaplan-Moss.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17022 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Carl Meyer
2011-10-22 04:30:10 +00:00
parent dca81ad58a
commit 145a77edc9
34 changed files with 635 additions and 208 deletions

View File

@@ -0,0 +1,66 @@
===============================
How to use Django with Gunicorn
===============================
.. highlight:: bash
Gunicorn_ ('Green Unicorn') is a pure-Python WSGI server for UNIX. It has no
dependencies and is easy to install and use.
.. _Gunicorn: http://gunicorn.org/
There are two ways to use Gunicorn with Django. One is to have Gunicorn treat
Django as just another WSGI application. The second is to use Gunicorn's
special `integration with Django`_.
.. _integration with Django: http://gunicorn.org/run.html#django-manage-py_
Installing Gunicorn
===================
Installing gunicorn is as easy as ``pip install gunicorn``. For more details,
see the `gunicorn documentation`_.
.. _gunicorn documentation: http://gunicorn.org/install.html
Running Django in Gunicorn as a generic WSGI application
========================================================
When Gunicorn is installed, a ``gunicorn`` command is available which starts
the Gunicorn server process. At its simplest, gunicorn just needs to be called
with a the location of a WSGI application object.::
gunicorn [OPTIONS] APP_MODULE
Where ``APP_MODULE`` is of the pattern ``MODULE_NAME:VARIABLE_NAME``. The
module name should be a full dotted path. The variable name refers to a WSGI
callable that should be found in the specified module.
So for a typical Django project, invoking gunicorn would look like::
gunicorn myproject.wsgi:application
(This requires that your project be on the Python path; the simplest way to
ensure that is to run this command from the same directory as your
``manage.py`` file.)
Using Gunicorn's Django integration
===================================
To use Gunicorn's built-in Django integration, first add ``"gunicorn"`` to
:setting:`INSTALLED_APPS`. Then run ``python manage.py run_gunicorn``.
This provides a few Django-specific niceties:
* sets the gunicorn process name to be that of the project
* validates installed models
* allows an ``--adminmedia`` option for passing in the location of the
admin media files, mimicing the behavior of runserver.
See Gunicorn's `deployment documentation`_ for additional tips on starting and
maintaining the Gunicorn server.
.. _deployment documentation: http://gunicorn.org/deploy.html

View File

@@ -0,0 +1,72 @@
=======================
How to deploy with WSGI
=======================
Django's primary deployment platform is WSGI_, the Python standard for web
servers and applications.
.. _WSGI: http://www.wsgi.org
Django's :djadmin:`startproject` management command sets up a simple default
WSGI configuration for you, which you can tweak as needed for your project, and
direct any WSGI-compliant webserver to use. Django includes getting-started
documentation for the following WSGI servers:
.. toctree::
:maxdepth: 1
modwsgi
gunicorn
uwsgi
The ``application`` object
--------------------------
One key concept of deploying with WSGI is to specify a central ``application``
callable object which the webserver uses to communicate with your code. This is
commonly specified as an object named ``application`` in a Python module
accessible to the server.
.. versionchanged:: 1.4
The :djadmin:`startproject` command creates a :file:`projectname/wsgi.py` that
contains such an application callable.
.. note::
Upgrading from a previous release of Django and don't have a :file:`wsgi.py`
file in your project? You can simply add one to your project's top-level
Python package (probably next to :file:`settings.py` and :file:`urls.py`)
with the contents below. If you want :djadmin:`runserver` to also make use
of this WSGI file, you can also add ``WSGI_APPLICATION =
"mysite.wsgi.application"`` in your settings (replacing ``mysite`` with the
name of your project).
Initially this file contains::
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
# This application object is used by the development server
# as well as any WSGI server configured to use this file.
from django.core.handlers.wsgi import get_wsgi_application
application = get_wsgi_application()
The ``os.environ.setdefault`` line just sets the default settings module to
use, if you haven't explicitly set the :envvar:`DJANGO_SETTINGS_MODULE`
environment variable. You'll need to edit this line to replace ``mysite`` with
the name of your project package, so the path to your settings module is
correct.
To apply `WSGI middleware`_ you can simply wrap the application object
in the same file::
from helloworld.wsgi import HelloWorldApplication
application = HelloWorldApplication(application)
You could also replace the Django WSGI application with a custom WSGI
application that later delegates to the Django WSGI application, if you want to
combine a Django application with a WSGI application of another framework.
.. _`WSGI middleware`: http://www.python.org/dev/peps/pep-3333/#middleware-components-that-play-both-sides

View File

@@ -0,0 +1,175 @@
==========================================
How to use Django with Apache and mod_wsgi
==========================================
Deploying Django with Apache_ and `mod_wsgi`_ is a tried and tested way to get
Django into production.
.. _Apache: http://httpd.apache.org/
.. _mod_wsgi: http://code.google.com/p/modwsgi/
mod_wsgi is an Apache module which can host any Python WSGI_ application,
including Django. Django will work with any version of Apache which supports
mod_wsgi.
.. _WSGI: http://www.wsgi.org
The `official mod_wsgi documentation`_ is fantastic; it's your source for all
the details about how to use mod_wsgi. You'll probably want to start with the
`installation and configuration documentation`_.
.. _official mod_wsgi documentation: http://www.modwsgi.org/
.. _installation and configuration documentation: http://www.modwsgi.org/wiki/InstallationInstructions
Basic configuration
===================
Once you've got mod_wsgi installed and activated, edit your Apache server's
``httpd.conf`` file and add::
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonPath /path/to/mysite.com
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
The first bit in the ``WSGIScriptAlias`` line is the base URL path you want to
serve your application at (``/`` indicates the root url), and the second is the
location of a "WSGI file" -- see below -- on your system, usually inside of
your project package (``mysite`` in this example). This tells Apache to serve
any request below the given URL using the WSGI application defined in that
file.
The ``WSGIPythonPath`` line ensures that your project package is available for
import on the Python path; in other words, that ``import mysite`` works.
The ``<Directory>`` piece just ensures that Apache can access your
:file:`wsgi.py` file.
Next we'll need to ensure this :file:`wsgi.py` with a WSGI application object
exists. As of Django version 1.4, :djadmin:`startproject` will have created one
for you; otherwise, you'll need to create it. See the :doc:`WSGI overview
documentation</howto/deployment/wsgi/index>` for the default contents you
should put in this file, and what else you can add to it.
Using a virtualenv
==================
If you install your project's Python dependencies inside a `virtualenv`_,
you'll need to add the path to this virtualenv's ``site-packages`` directory to
your Python path as well. To do this, you can add another line to your
Apache configuration::
WSGIPythonPath /path/to/your/venv/lib/python2.X/site-packages
Make sure you give the correct path to your virtualenv, and replace
``python2.X`` with the correct Python version (e.g. ``python2.7``).
.. _virtualenv: http://www.virtualenv.org
Using mod_wsgi daemon mode
==========================
"Daemon mode" is the recommended mode for running mod_wsgi (on non-Windows
platforms). See the `official mod_wsgi documentation`_ for details on setting
up daemon mode. The only change required to the above configuration if you use
daemon mode is that you can't use ``WSGIPythonPath``; instead you should use
the ``python-path`` option to ``WSGIDaemonProcess``, for example::
WSGIDaemonProcess example.com python-path=/path/to/mysite.com:/path/to/venv/lib/python2.7/site-packages
.. _serving-files:
Serving files
=============
Django doesn't serve files itself; it leaves that job to whichever Web
server you choose.
We recommend using a separate Web server -- i.e., one that's not also running
Django -- for serving media. Here are some good choices:
* lighttpd_
* Nginx_
* TUX_
* A stripped-down version of Apache_
* Cherokee_
If, however, you have no option but to serve media files on the same Apache
``VirtualHost`` as Django, you can set up Apache to serve some URLs as
static media, and others using the mod_wsgi interface to Django.
This example sets up Django at the site root, but explicitly serves
``robots.txt``, ``favicon.ico``, any CSS file, and anything in the
``/static/`` and ``/media/`` URL space as a static file. All other URLs
will be served using mod_wsgi::
Alias /robots.txt /path/to/mysite.com/static/robots.txt
Alias /favicon.ico /path/to/mysite.com/static/favicon.ico
AliasMatch ^/([^/]*\.css) /path/to/mysite.com/static/styles/$1
Alias /media/ /path/to/mysite.com/media/
Alias /static/ /path/to/mysite.com/static/
<Directory /path/to/mysite.com/static>
Order deny,allow
Allow from all
</Directory>
<Directory /path/to/mysite.com/media>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Order allow,deny
Allow from all
</Files>
</Directory>
.. _lighttpd: http://www.lighttpd.net/
.. _Nginx: http://wiki.nginx.org/Main
.. _TUX: http://en.wikipedia.org/wiki/TUX_web_server
.. _Apache: http://httpd.apache.org/
.. _Cherokee: http://www.cherokee-project.com/
.. More details on configuring a mod_wsgi site to serve static files can be found
.. in the mod_wsgi documentation on `hosting static files`_.
.. _hosting static files: http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Hosting_Of_Static_Files
.. _serving-the-admin-files:
Serving the admin files
=======================
Note that the Django development server automatically serves the static files
of the admin app (and any other installed apps), but this is not the case when
you use any other server arrangement. You're responsible for setting up Apache,
or whichever media server you're using, to serve the admin files.
The admin files live in (:file:`django/contrib/admin/static/admin`) of the
Django distribution.
We **strongly** recommend using :mod:`django.contrib.staticfiles` (along with
a Web server as outlined in the previous section) to handle the admin files, but
here are three other approaches:
1. Create a symbolic link to the admin static files from within your
document root (this may require ``+FollowSymLinks`` in your Apache
configuration).
2. Use an ``Alias`` directive, as demonstrated above, to alias the appropriate
URL (probably :setting:`STATIC_URL` + `admin/`) to the actual location of
the admin files.
3. Copy the admin static files so that they live within your Apache
document root.

View File

@@ -0,0 +1,265 @@
============================
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 also provides a fast `caching framework`_ but its documentation is not the
purpose of this document.
.. _uWSGI: http://projects.unbit.it/uwsgi/
.. _caching framework: http://projects.unbit.it/uwsgi/wiki/CachingFramework
Prerequisite: uWSGI
===================
The wiki describes several `installation procedures`_. Using pip, the python
package manager, installing any uWSGI version can be done with one command
line. For example::
# install current stable version
pip install uwsgi
# or install LTS (long term support)
pip install http://projects.unbit.it/downloads/uwsgi-lts.tar.gz
.. _installation procedures: http://projects0.unbit.it/uwsgi/wiki/Install
Prerequisite: general concept
=============================
uWSGI model
-----------
uWSGI operates on a client-server model. Your Web server (ie. nginx, Apache)
communicates with a django-uwsgi "worker" process to serve dynamic content.
The Web server can communicate with the uWSGI process either:
* directly by the uWSGI protocol through a socket created by uWSGI,
* or by proxying HTTP requests to the minimalist HTTP server built in uWSGI.
In the first case: the Web server can do uWSGI protocol (often with a
module). It can then use either a Unix domain socket (a "named pipe" on Win32
systems), or it can use a TCP socket. What you choose is a matterr of
preference. Usually, a TCP socket is easier because connecting to a port
doesn't require special permissions.
In the second case, the Web server doesn't need to speak the uWSGI protocol. It
just needs to be able to proxy HTTP requests to the HTTP server built-in uWSGI.
The procedure is the same as proxying to any HTTP server. Note that the Web
server is a "reverse proxy" in this case.
Configuring the uWSGI server
----------------------------
In any case, when you set up your Web server, you'll just need to point its
uwsgi or proxy module to the host/port or socket you specified when starting
the uWSGI server.
.. admonition:: Choosing the socket
The easiest is to set the socket to a high level (>49152) local port like
127.0.0.1:49152. If the socket is a file, the system administrator must
ensure that the Web server process has read, write and execute privileges
on that file.
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 is not a substitute the
official manual and online documentation.
uWSGI supports configuration through:
* environment variables
* command line switches
* ldap
* ini files
* xml files
* yaml files
Managing the uWSGI server
-------------------------
The system administrator controls the worker process pool by sending signals
to the master process. For example, the unix kill command sends such signals.
uWSGI can write the master process id to a "pidfile". A "pidfile" is a plain
text file containing just a process id.
Starting the server
-------------------
Starting an uWSGI server is the role of the system administrator, like
starting the Web server. It is *not* the role of the Web server to start the
uWSGI server. This means:
* the uWSGI server can be restarted or reloaded independently from the Web
server,
* (except with Cherokee), it is the role of the system administrator to make
uWSGI start on boot or reboot: either through tools like supervisor or
daemontools, either directly at init level in a file like /etc/rc.local or
/etc/conf.d/local
Managing uWSGI
==============
Starting the server
-------------------
Example command line for a Web server that understands the uWSGI protocol::
uwsgi --chdir=/path/to/your/project
--module='mysite.wsgi:application' \
--env DJANGO_SETTINGS_MODULE=mysite.settings \
--master --pidfile=/tmp/project-master.pid \
--socket=127.0.0.1:49152 \ # can also be a file
--processes=5 \ # number of worker processes
--uid=1000 --gid=2000 \ # if root, uwsgi can drop privileges
--harakiri=20 \ # respawn processes taking more than 20 seconds
--limit-as=128 \ # limit the project to 128 Megabytes
--max-requests=5000 \ # respawn processes after serving 5000 requests
--vacuum \ # clear environment on exit
--home=/path/to/virtual/env \ # optionnal path to a virtualenv
--daemonize=/var/log/uwsgi/yourproject.log # background the process
This assumes that you have a top-level project package named ``mysite``, and
within it a module :file:`mysite/wsgi.py` that contains a WSGI ``application``
object. This is the layout you will have if you ran ``django-admin.py
startproject mysite`` (using your own project name in place of ``mysite``) with
a recent version of Django. If this file does not exist, you'll need to create
it. See the :doc:`/howto/deployment/wsgi/index` documentation for the default
contents you should put in this file, and what else you can add to it.
The Django-specific options here are:
* ``chdir``: the path to the directory that needs to be on Python's import path; i.e. the directory containing the ``mysite`` package.
* ``module``: The WSGI module to use, probably the ``mysite.wsgi`` module which
:djadmin:`startproject` creates.
* ``env``: should probably contain at least ``DJANGO_SETTINGS_MODULE``
* ``home``: optional path to your project virtualenv
Example ini configuration file::
[uwsgi]
chdir=/path/to/your/project
module='mysite.wsgi:application'
master=True
pidfile=/tmp/project-master.pid
vacuum=True
max-requests=5000
deamonize=/var/log/uwsgi/yourproject.log
Example ini configuration file usage::
uwsgi --ini uwsgi.ini
Read more `uWSGI configuration examples
<http://projects.unbit.it/uwsgi/wiki/Example>`_.
.. admonition:: Massive application hosting
`uWSGI emperor <http://projects.unbit.it/uwsgi/wiki/Emperor>`_ is a special
uWSGI process that can manage many master processes at once.
Reloading the daemon
--------------------
As mentioned above, the uWSGI master process is one of the core components 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 losing any requests.
For example, uWSGI can be signaled that worker should reload the code after
handling their current request (if any) from bash::
# using kill to send the signal
kill -HUP `cat /tmp/project-master.pid`
# if uwsgi was started with --touch-reload=/tmp/somefile
touch /tmp/somefile
Or from Python::
uwsgi.reload()
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`
HTTP server configuration
=========================
Nginx setup
-----------
Nginx provides the `uwsgi module <http://wiki.nginx.org/HttpUwsgiModule>`_ by
default since nginx 0.8.40. Configuring Nginx to use an uWSGI server is as
simple as setting it up to proxy requests::
location / {
uwsgi_pass 127.0.0.1:49152;
# 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 setup is documented in the `official Cherokee uWSGI documentation
<http://www.cherokee-project.com/doc/cookbook_uwsgi.html>`_.
Lighttpd setup
--------------
`Lighttpd uwsgi module <http://projects.unbit.it/uwsgi/wiki/RunOnLighttpd>`_ is
still experimental.
Troubleshooting
===============
As usual, the first thing to do is to check the logs. This implies:
* the web server log, which will indicate if it couldn't connect to the uWSGI
process,
* the uWSGI log, which will indicate if an exception was thrown.
Typical gotchas:
* If the socket is a file, the Web server process should have read, write and
execute permissions on the socket file. The ``--chmod-socket`` option can do
it.
* In some cases, for instance if uWSGI was started without ``--vacuum`` or
killed with ``SIGKILL``, it won't remove the socket and pidfile when it is
interrupted. It is safe to remove them manually and to start uWSGI again in
that case.
* uWSGI can start the process in the foreground, this will make errors easily
visible to the system administrator.