Skip to content

Commit

Permalink
Some edits to the new docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
davisp committed Mar 26, 2010
1 parent 8d52e1e commit 4dbde5c
Show file tree
Hide file tree
Showing 13 changed files with 323 additions and 146 deletions.
26 changes: 18 additions & 8 deletions README.rst
@@ -1,9 +1,12 @@
About
-----

gunicorn 'Green Unicorn' is a WSGI HTTP Server for UNIX handle fast clients **and** sleepy application.
gunicorn 'Green Unicorn' is a WSGI HTTP Server for UNIX handle fast clients
**and** sleepy application.

This is a port of Unicorn (http://unicorn.bogomips.org/) in Python. Meet us on `#gunicorn irc channel <http://webchat.freenode.net/?channels=gunicorn>`_ on `Freenode`_.
This is a port of Unicorn (http://unicorn.bogomips.org/) in Python. Meet us
on `#gunicorn irc channel <http://webchat.freenode.net/?channels=gunicorn>`_
on `Freenode`_.

Installation
------------
Expand All @@ -18,13 +21,21 @@ Or from Pypi::

$ easy_install -U gunicorn
If you want to handle `sleepy application <http://gunicorn.org/faq.html>`_ you will need to install `Eventlet`_ or `Gevent`_.
If you want to handle `sleepy applications <http://gunicorn.org/faq.html>`_
you will need to install `Eventlet`_ or `Gevent`_.

To install eventlet::

$ easy_install -U eventlet

Replace `eventlet` by **gevent** if you want to use `gevent`. You can now launch gunicorn with Eventlet or Gevent arbiter, see `Gunicorn usage <http://gunicorn.org/usage.html>`_ for more information.
Replace `eventlet` by **gevent** if you want to use `gevent`. You can now
launch gunicorn with Eventlet or Gevent arbiter, see `Gunicorn usage
<http://gunicorn.org/usage.html>`_ for more information.

If you encounter errors when compiling the extensions for `gevent` or
`eventlet` you probably need to install a newer version of libev_.

.. _libev: http://software.schmorp.de/pkg/libev.html

Usage
-----
Expand All @@ -42,8 +53,8 @@ Usage
-w WORKERS, --workers=WORKERS
Number of workers to spawn. [1]
-a ARBITER, --arbiter=ARBITER
gunicorn arbiter entry point or module
[egg:gunicorn#main]
gunicorn arbiter entry point or module
[egg:gunicorn#main]
-p PIDFILE, --pid=PIDFILE
set the background PID FILE
-D, --daemon Run daemonized in the background.
Expand All @@ -53,15 +64,14 @@ Usage
-g GROUP, --group=GROUP
Change worker group
-n APP_NAME, --name=APP_NAME
Application name
Application name
--log-level=LOGLEVEL Log level below which to silence messages. [info]
--log-file=LOGFILE Log to a file. - equals stdout. [-]
-d, --debug Debug mode. only 1 worker.
--version show program's version number and exit
-h, --help show this help message and exit


Example with test app::

$ cd examples
Expand Down
76 changes: 48 additions & 28 deletions doc/htdocs/configuration.html
Expand Up @@ -49,29 +49,29 @@ <h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>

<div class="document" id="the-configuration-file">
<h1 class="title">The Configuration File</h1>
<p>Gunciorn 0.5 introduced the ability to use a Python configuration file. Gunicorn will look for <tt class="docutils literal">gunicorn.conf.py</tt> in the current working directory or what ever path is specified on the command line with the <tt class="docutils literal"><span class="pre">-c</span></tt> option.</p>
<p>Gunciorn 0.5 introduced the ability to use a Python configuration file. Gunicorn will look for <tt class="docutils literal"><span class="pre">gunicorn.conf.py</span></tt> in the current working directory or what ever path is specified on the command line with the <tt class="docutils literal"><span class="pre">-c</span></tt> option.</p>
<div class="section" id="example-gunicorn-conf-py">
<h1>Example gunicorn.conf.py</h1>
<pre class="literal-block">
arbiter = &quot;egg:gunicorn&quot; # Or &quot;egg:gunicorn#eventlet&quot; (eventlet or gevent)
backlog = 2048
bind = &quot;127.0.0.1:8000&quot; # Or &quot;unix:/tmp/gunicorn.sock&quot;
daemon = False # Whether work in the background
debug = False # Some extra logging
keepalive = 2 # Time we wait for next connection (in ms)
logfile = &quot;-&quot; # Name of the log file
loglevel = &quot;info&quot; # The level at which to log
pidfile = None # Path to a PID file
workers = 1 # Number of workers to initialize
umask = 0 # Umask to set when daemonizing
user = None # Change process owner to user
group = None # Change process group to group
proc_name = None # Change the process name
tmp_upload_dir = None # Set path used to store temporary uploads
worker_connections=1000 # Number of connections accepted by a worker
arbiter = &quot;egg:gunicorn&quot; # The arbiter to use for worker management
backlog = 2048 # The listen queue size for the server socket
bind = &quot;127.0.0.1:8000&quot; # Or &quot;unix:/tmp/gunicorn.sock&quot;
daemon = False # Whether work in the background
debug = False # Some extra logging
keepalive = 2 # Time we wait for next connection (in seconds)
logfile = &quot;-&quot; # Name of the log file
loglevel = &quot;info&quot; # The level at which to log
pidfile = None # Path to a PID file
workers = 1 # Number of workers to initialize
umask = 0 # Umask to set when daemonizing
user = None # Change process owner to user
group = None # Change process group to group
proc_name = None # Change the process name
tmp_upload_dir = None # Set path used to store temporary uploads
worker_connections=1000 # Maximum number of simultaneous connections

after_fork=lambda server, worker: server.log.info(
&quot;Worker spawned (pid: %s)&quot; % worker.pid),
&quot;Worker spawned (pid: %s)&quot; % worker.pid)

before_fork=lambda server, worker: True

Expand All @@ -84,37 +84,57 @@ <h1>Parameter Descriptions</h1>
<dt>after_fork(server, worker):</dt>
<dd>This is called by the worker after initialization.</dd>
<dt>arbiter:</dt>
<dd>The arbiter you want to use. An arbiter maintain the workers processes alive. It launches or kills them if needed. It also manages application reloading via SIGHUP/USR2. By default it's <cite>egg:gunicorn#main</cite>. This arbiter only support fast clients connections. If you need to create a sleepy application or handling keepalive set it to <cite>egg:gunicorn#eventlet</cite> to use it with <a class="reference external" href="http://eventlet.net">Eventlet</a> or <cite>egg:gunicorn#gevent</cite> with <a class="reference external" href="http://gevent.org">Gevent</a>. Eventlet arbiter can also be used with <a class="reference external" href="http://twistedmatrix.com">Twisted</a> by using its <a class="reference external" href="http://bitbucket.org/which_linden/eventlet/src/tip/README.twisted">helper</a>.</dd>
<dd><p class="first">The arbiter manages the worker processes that actually serve clients. It
handles launching new workers and killing misbehaving workers among
other things. By default the arbiter is <cite>egg:gunicorn#main</cite>. This arbiter
only supports fast request handling requiring a buffering HTTP proxy.</p>
<p class="last">If your application requires the ability to handle prolonged requests to
provide long polling, comet, or calling an external web service you'll
need to use an async arbiter. Gunicorn has two async arbiters built in
using <a class="reference external" href="http://eventlet.net">Eventlet</a> or <a class="reference external" href="http://gevent.org">Gevent</a>. You can also use the Evenlet arbiter with
the <a class="reference external" href="http://twistedmatrix.com">Twisted</a> helper.</p>
</dd>
<dt>backlog:</dt>
<dd>The backlog parameter defines the maximum length for the queue of pending connections see listen(2) for more information. The default is 2048.</dd>
<dd>The backlog parameter defines the maximum length for the queue of pending
connections. The default is 2048. See listen(2) for more information</dd>
<dt>before_fork(server, worker):</dt>
<dd>This is called by the worker just before forking.</dd>
<dt>before_exec(server):</dt>
<dd>This function is called before relaunching the master. This happens when the master receives a HUP or USR2 signal.</dd>
<dd>This function is called before relaunching the master. This happens when
the master receives a HUP or USR2 signal.</dd>
<dt>bind:</dt>
<dd>The address on which workers are listening. It can be a TCP address with a format of <tt class="docutils literal">IP:PORT</tt> or a Unix socket address like <tt class="docutils literal"><span class="pre">unix:/path/to/socketfile</span></tt>.</dd>
<dd>The address on which workers are listening. It can be a TCP address with a
format of <tt class="docutils literal"><span class="pre">IP:PORT</span></tt> or a Unix socket address like
<tt class="docutils literal"><span class="pre">unix:/path/to/socketfile</span></tt>.</dd>
<dt>daemon:</dt>
<dd>Whether or not to detach the server from the controlling terminal.</dd>
<dt>debug:</dt>
<dd>If <tt class="docutils literal">True</tt>, only one worker will be launch and the variable <tt class="docutils literal">wsgi.multiprocess</tt> will be set to False.</dd>
<dd>If <tt class="docutils literal"><span class="pre">True</span></tt>, only one worker will be launch and the variable
<tt class="docutils literal"><span class="pre">wsgi.multiprocess</span></tt> will be set to False.</dd>
<dt>group:</dt>
<dd>The group in which worker processes will be launched.</dd>
<dt>keepalive:</dt>
<dd>Keepalive timeout. The default is 2 seconds, which should be enough under most conditions for browsers to render the page and start retrieving extra elements for. Increasing this beyond 5 seconds is not recommended. Zero disables keepalive entirely.</dd>
<dd>KeepAlive timeout. The default is 2 seconds, which should be enough under
most conditions for browsers to render the page and start retrieving extra
elements for. Increasing this beyond 5 seconds is not recommended. Zero
disables KeepAlive entirely.</dd>
<dt>logfile:</dt>
<dd>The path to the log file <tt class="docutils literal">-</tt> (stdout) by default.</dd>
<dd>The path to the log file <tt class="docutils literal"><span class="pre">-</span></tt> (stdout) by default.</dd>
<dt>loglevel:</dt>
<dd>The level at which to log. <tt class="docutils literal">info</tt>, <tt class="docutils literal">debug</tt>, or <tt class="docutils literal">error</tt> for instance. Only log messages of equal or greater severity are logged.</dd>
<dd>The level at which to log. <tt class="docutils literal"><span class="pre">info</span></tt>, <tt class="docutils literal"><span class="pre">debug</span></tt>, or <tt class="docutils literal"><span class="pre">error</span></tt> for instance.
Only log messages of equal or greater severity are logged.</dd>
<dt>pidfile:</dt>
<dd>A file to store the master's PID.</dd>
<dt>proc_name:</dt>
<dd>If <a class="reference external" href="http://pypi.python.org/pypi/setproctitle">setproctitle</a> is installed, it allows you to set the process name for this Gunicorn instance.</dd>
<dd>A name for the master process. Only takes effect if <a class="reference external" href="http://pypi.python.org/pypi/setproctitle">setproctitle</a> is
installed. This alters the process names listed by commands like <tt class="docutils literal"><span class="pre">ps</span></tt>.</dd>
<dt>umask:</dt>
<dd>Used to set the umask when daemonizing.</dd>
<dt>user:</dt>
<dd>The user as which worker processes will by launched.</dd>
<dt>worker_connections:</dt>
<dd>Number of connections a worker can handle when used with Eventlet or Gevent arbiter. The default is 1000.</dd>
<dd>Number of simultaneous connections a worker can handle when used with
Eventlet or Gevent arbiter. The default is 1000.</dd>
<dt>tmp_upload_dir:</dt>
<dd>Set the path used to store temporarily the body of the request.</dd>
</dl>
Expand Down
38 changes: 34 additions & 4 deletions doc/htdocs/deployment.html
Expand Up @@ -49,10 +49,38 @@ <h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>

<div class="document" id="production-setup">
<h1 class="title">Production Setup</h1>
<p>Although there are many HTTP proxies available, we strongly advise that you use <a class="reference external" href="http://www.nginx.org">Nginx</a>. If you choose another proxy server you need to make sure that it buffers slow clients when you use default Gunicorn arbiter. Without this buffering Gunicorn will be easily susceptible to Denial-Of-Service attacks.</p>
<p>There are two general classes of configuration for Gunicorn. For the time
being these will are referred to as &quot;fast clients&quot; and &quot;sleepy applications&quot;.</p>
<div class="section" id="fast-clients">
<h1>Fast Clients</h1>
<p>Generally speaking when we say &quot;fast clients&quot; what we really mean is that the
time taken to process a client from the time a socket is accepted until
the time the socket is closed is well defined to be short. This means that
clients are buffered by an upstream proxy (otherwise clients can send or
receive data slowly) and that your application code does not have major
blocking sections (a web request to the internet might occasionally take a
non trivial amount of time).</p>
<p>Traditional webapps are generally fine for fast client configurations.
Deployments should generally default to this type of configuration unless it is
known that the application code wants to do long-polling, comet, web sockets or
has other potentially long operations (on the order of seconds).</p>
</div>
<div class="section" id="sleepy-applications">
<h1>Sleepy Applications</h1>
<p>Any application that requires an undefined amount of time for client processing
is considered a sleepy application. If you are wanting a platform that is
capable of handling comet connections, long polling, or potentially long
blocking operations (requests to external web services, ie Facebook Connect)
then you'll want to use an async arbiter.</p>
</div>
<div class="section" id="nginx-config-for-fast-clients-handling">
<h1>Nginx Config for fast clients handling</h1>
<p>An <a class="reference external" href="http://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf">example configuration</a> file for use with <a class="reference external" href="http://www.nginx.org">Nginx</a>:</p>
<p>Although there are many HTTP proxies available, we strongly advise that you
use <a class="reference external" href="http://www.nginx.org">Nginx</a>. If you choose another proxy server you need to make sure that it
buffers slow clients when you use default Gunicorn arbiter. Without this
buffering Gunicorn will be easily susceptible to Denial-Of-Service attacks.
You can use <a class="reference external" href="http://ha.ckers.org/slowloris/">slowloris</a> to check if your proxy is behaving properly.</p>
<p>An <a class="reference external" href="http://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf">example configuration</a> file for fast clients with <a class="reference external" href="http://www.nginx.org">Nginx</a>:</p>
<pre class="literal-block">
worker_processes 1;

Expand Down Expand Up @@ -105,7 +133,8 @@ <h1>Nginx Config for fast clients handling</h1>
}
}
</pre>
<p>To handle sleepy applications, just add the line <cite>proxy_buffering off;</cite> under the proxy_redirect directive:</p>
<p>To handle sleepy applications, just add the line <cite>proxy_buffering off;</cite> under
the proxy_redirect directive:</p>
<pre class="literal-block">
...
location / {
Expand All @@ -124,7 +153,8 @@ <h1>Nginx Config for fast clients handling</h1>
</div>
<div class="section" id="daemon-monitoring">
<h1>Daemon Monitoring</h1>
<p>A popular method for deploying Gunicorn is to have it monitored by <a class="reference external" href="http://smarden.org/runit/">runit</a>. An <a class="reference external" href="http://github.com/benoitc/gunicorn/blob/master/examples/gunicorn_rc">example service</a> definition:</p>
<p>A popular method for deploying Gunicorn is to have it monitored by <a class="reference external" href="http://smarden.org/runit/">runit</a>.
An <a class="reference external" href="http://github.com/benoitc/gunicorn/blob/master/examples/gunicorn_rc">example service</a> definition:</p>
<pre class="literal-block">
#!/bin sh

Expand Down
17 changes: 9 additions & 8 deletions doc/htdocs/faq.html
Expand Up @@ -50,18 +50,19 @@ <h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div class="document" id="faq">
<h1 class="title">FAQ</h1>
<dl class="docutils">
<dt>What is a slow client?</dt>
<dd>A slow client is defined as a request that can take an arbitrary amount of
time to send or read a request. Sometimes due to network performance or
because it is a malicious client attempting to cause problems. Check out
the <a class="reference external" href="http://ha.ckers.org/slowloris/">slowloris</a> script to generate slow client traffic.</dd>
<dt>What is a fast client?</dt>
<dd>Generally speaking a fast client is something that is being served over the
local network or from the same machine. This generally would refer to requests
forwarded from an upstream proxy. Also see the above FAQ for what a fast
client is not.</dd>
<dt>What is a slow client?</dt>
<dd>A slow client is defined as a request that can take an arbitrary amount of
time to send a request or read a response. Sometimes due to network
performance or because it is a malicious client attempting to cause problems.
Check out the <a class="reference external" href="http://ha.ckers.org/slowloris/">slowloris</a> script to generate slow client traffic.</dd>
<dt>What are sleepy applications?</dt>
<dd>Applications that expect long request/response times and/or slow clients. Gunicorn use <a class="reference external" href="http://eventlet.net">Eventlet</a> or <a class="reference external" href="http://gevent.org">Gevent</a> to manage concurrency.</dd>
<dd>Applications that expect long request/response times and/or slow clients.
Gunicorn use <a class="reference external" href="http://eventlet.net">Eventlet</a> or <a class="reference external" href="http://gevent.org">Gevent</a> to manage concurrency.</dd>
<dt>How might I test a proxy configuration?</dt>
<dd>Check out <a class="reference external" href="http://ha.ckers.org/slowloris/">slowloris</a> for a script that will generate significant slow
traffic. If your application remains responsive through out that test you
Expand All @@ -83,8 +84,8 @@ <h1 class="title">FAQ</h1>
</pre>
</dd>
<dt>How do I set SCRIPT_NAME?</dt>
<dd>By default <tt class="docutils literal">SCRIPT_NAME</tt> is an empy string. The value could be set by
setting <tt class="docutils literal">SCRIPT_NAME</tt> in the environment or as an HTTP header.</dd>
<dd>By default <tt class="docutils literal"><span class="pre">SCRIPT_NAME</span></tt> is an empy string. The value could be set by
setting <tt class="docutils literal"><span class="pre">SCRIPT_NAME</span></tt> in the environment or as an HTTP header.</dd>
<dt>How to name processes?</dt>
<dd>You need to install the Python package <a class="reference external" href="http://pypi.python.org/pypi/setproctitle">setproctitle</a>. Then you can name
your process with <cite>-n</cite> or just let the default. If you use a configuration
Expand Down

0 comments on commit 4dbde5c

Please sign in to comment.