Large refactor of the documentation and website.

This commit is contained in:
Paul J. Davis 2010-05-22 01:11:13 -04:00
parent 648c246ed1
commit 3c7d5320fa
78 changed files with 2384 additions and 986 deletions

View File

@ -8,6 +8,7 @@ from __future__ import with_statement
import codecs
import datetime
import inspect
import os
import subprocess as sp
import sys
@ -52,7 +53,7 @@ class Site(object):
print ""
print "Updating css..."
try:
sp.check_call(["compass", "compile"])
sp.check_call(["compass", "compile", "--boring"])
except sp.CalledProcessError:
print "Failed to update CSS"
@ -89,6 +90,8 @@ class Page(object):
basename, oldext = os.path.splitext(filename)
oldext = oldext.lower()[1:]
converter = getattr(self, "convert_%s" % oldext, lambda x: x)
if "insert_settings" in self.headers:
body = body % {"settings": self.format_settings()}
self.body = converter(body)
newext = self.headers.get('ext', '.html')
@ -120,14 +123,108 @@ class Page(object):
if not tmpl_name:
return self.body
kwargs = {"conf": conf, "body": self.body, "url": self.url()}
kwargs = {
"conf": conf,
"body": self.body,
"url": self.url()
}
kwargs.update(self.headers)
return self.site.get_template(tmpl_name).render(kwargs)
def convert_rst(self, body):
parts = publish_parts(source=body, writer_name="html")
overrides = {"initial_header_level": 2}
parts = publish_parts(
source=body,
writer_name="html",
settings_overrides=overrides
)
return parts['html_body']
def format_settings(self):
currdir = os.path.dirname(__file__)
sys.path.insert(0, os.path.join(currdir, ".."))
import gunicorn.config as guncfg
ret = []
for i, s in enumerate(guncfg.KNOWN_SETTINGS):
if i == 0 or s.section != guncfg.KNOWN_SETTINGS[i-1].section:
ret.append("%s\n%s\n\n" % (s.section, "+" * len(s.section)))
ret.append(self.fmt_setting2(s))
return ''.join(ret)
def fmt_setting2(self, s):
if callable(s.default):
val = inspect.getsource(s.default)
val = "\n".join(" %s" % l for l in val.splitlines())
val = " ::\n\n" + val
else:
val = "``%s``" % s.default
if s.cli and s.meta:
args = ["%s %s" % (arg, s.meta) for arg in s.cli]
cli = ', '.join(args)
elif s.cli:
cli = ", ".join(s.cli)
out = []
out.append("%s" % s.name)
out.append("~" * len(s.name))
out.append("")
if s.cli:
out.append("* ``%s``" % cli)
out.append("* %s" % val)
out.append("")
out.append(s.desc)
out.append("")
out.append("")
return "\n".join(out)
def fmt_setting(self, s):
out = []
lines = s.desc.splitlines()
width = max(map(lambda x: len(x), lines))
if not callable(s.default):
val = '%s' % s.default
else:
val = ''
if s.cli and s.meta:
args = ["%s %s" % (arg, s.meta) for arg in s.cli]
cli = ', '.join(args)
elif s.cli:
cli = ", ".join(s.cli)
else:
cli = "N/A"
width = 80
namelen = 20
deflen = 20
clilen = width - (namelen + deflen + 4)
args = ("-" * namelen, "-" * deflen, "-" * clilen)
out.append("+%s+%s+%s+" % args)
names = "| %s" % s.name
names += " " * (namelen - (len(s.name) + 2))
names += " | %s" % val
names += " " * (deflen - (len(val) + 2))
names += " | %s" % cli
names += " " * (clilen - (len(cli) + 1))
names += "|"
out.append(names)
out.append(out[0].replace("-", "="))
for l in lines:
l = l.rstrip("\n")
if len(l) < width:
l += " " * ((width - 2) - len(l))
out.append("|%s|" % l)
out.append("+%s+" % ("-" * (width - 2)))
out.extend(["", ""])
return "\n".join(out)
def main():
Site().render()

View File

@ -1,10 +1,159 @@
@import compass/css3
@import compass/reset
@import compass/utilities/general
@import compass/utilities/lists
$bg_color: #F9F9F9
$font_color: #2A2A2A
$separator: #CCCCCC
$size_body_width: 700px
$size_toc_width: 150px
$color_a: #569633
$color_bg: #F9F9F9
$color_font: #2A2A2A
$color_footer_a: #444444
$color_footer_border: #CCCCCC
$color_headings: #489848
$color_headings_border: #CCCCCC
$color_menu_border: #BBBBBB
$color_menu_a: #489848
$color_note_before: #489848
$color_note_border: #489848
$color_pre_bg: #FFFFDD
$color_th_border: #000000
body
background: $bg_color
color: $font_color
background: $color_bg
color: $color_font
line-height: 18px
font-family: Arial, sans-serif
font-size: 13px
div.container
display: block
width: $size_body_width
margin: 0 auto
#header
margin: 1em auto
text-align: center
#menu
width: 100%
margin: 1em 0
border-bottom: 1px solid $color_menu_border
text-align: center
ul
+no-bullets
display: inline
li
display: inline
margin-right: 15px
text-align: center
a
font-size: 20px
font-weight: 700
color: $color_menu_a
text-decoration: none
#contents.sidebar
float: right
width: $size_toc_width
ul
margin-bottom: 0.2em
p.topic-title
display: none
div.section
margin-right: $size_toc_width + 20px
div.section div.section
margin-right: 0
div.section ul
margin-left: 15px
+no-bullets
h1, h2, h3, h4
color: $color_headings
h1
margin-top: 10px
font-size: 26px
h2
border-bottom: 5px solid $color_headings_border
margin-bottom: 13px
padding-bottom: 3px
font-size: 20px
font-weight: 700
h3
border-bottom: 1px solid $color_headings_border
margin-bottom: 13px
font-weight: 700
a
color: $color_a
text-decoration: none
p
margin-bottom: 1em
font-size: 1em
ol
list-style: decimal
margin-left: 2em
margin-bottom: 13px
ul
list-style: disc
margin-left: 2em
margin-bottom: 13px
pre, tt
font-family: 'andale mono', 'lucida console', monospace
font-size: 12px
background: $color_pre_bg
pre
white-space: pre
margin: 3px 3px 2em 3px
padding: 8px 20px
.note
border-top: 1px solid $color_note_border
border-bottom: 1px solid $color_note_border
padding: .6em .6em .6em 80px
margin-bottom: 2em
position: relative
p.admonition-title:before
content: "!"
font-size: 60px
font-weight: bold
color: $color_note_before
position: absolute
top: 30px
left: 30px
font-family: helvetica,arial
p.admonition-title
font-weight: 700
margin: 0
margin-bottom: 4px
padding: 0
p.last
padding: 0
margin: 0
#footer
border-top: 1px solid $color_footer_border
clear: both
display: block
width: 100%
margin-top: 3em
padding-top: 1em
text-align: center
font-size: 0.8em
a
color: $color_footer_a

View File

@ -4,56 +4,31 @@
<meta charset="utf-8" />
<title>Green Unicorn - The Configuration File</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<!--[if IE]>
<script>
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('nav');
document.createElement('time');
</script>
<![endif]-->
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div id="links">
Get the source via
<a href="http://github.com/benoitc/gunicorn">git</a>, then
<a href="http://github.com/benoitc/gunicorn/issues">send feedback</a>
</div>
</div>
<div id="menu">
<ul id="actions">
<li><a href="installation.html">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="deployment.html">Deployment</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="tuning.html">Tuning</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="the-configuration-file">
<div class="container">
<div id="header">
<a href="http://gunicorn.org">
<img src="/images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="the-configuration-file">
<h1 class="title">The Configuration File</h1>
<p>Gunicorn 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>
<div class="section" id="example-gunicorn-conf-py">
<h1>Example gunicorn.conf.py</h1>
<h2>Example gunicorn.conf.py</h2>
<pre class="literal-block">
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;
@ -85,7 +60,7 @@ before_exec=lambda server: server.log.info(&quot;Forked child, reexecuting&quot;
</pre>
</div>
<div class="section" id="parameter-descriptions">
<h1>Parameter Descriptions</h1>
<h2>Parameter Descriptions</h2>
<dl class="docutils">
<dt>after_fork(server, worker):</dt>
<dd>This is called by the worker after initialization.</dd>
@ -150,12 +125,10 @@ Eventlet or Gevent arbiter. The default is 1000.</dd>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</div>
</body>
</html>

470
doc/htdocs/configure.html Normal file
View File

@ -0,0 +1,470 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Green Unicorn - Configure</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
<div class="document">
<div class="contents sidebar topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
<li><a class="reference internal" href="#framework-settings" id="id2">Framework Settings</a><ul>
<li><a class="reference internal" href="#paster-applications" id="id3">Paster Applications</a></li>
</ul>
</li>
<li><a class="reference internal" href="#configuration-file" id="id4">Configuration File</a></li>
<li><a class="reference internal" href="#command-line" id="id5">Command Line</a></li>
<li><a class="reference internal" href="#settings" id="id6">Settings</a><ul>
<li><a class="reference internal" href="#config-file" id="id7">Config File</a><ul>
<li><a class="reference internal" href="#config" id="id8">config</a></li>
</ul>
</li>
<li><a class="reference internal" href="#server-socket" id="id9">Server Socket</a><ul>
<li><a class="reference internal" href="#bind" id="id10">bind</a></li>
<li><a class="reference internal" href="#backlog" id="id11">backlog</a></li>
</ul>
</li>
<li><a class="reference internal" href="#worker-processes" id="id12">Worker Processes</a><ul>
<li><a class="reference internal" href="#workers" id="id13">workers</a></li>
<li><a class="reference internal" href="#worker-class" id="id14">worker_class</a></li>
<li><a class="reference internal" href="#worker-connections" id="id15">worker_connections</a></li>
<li><a class="reference internal" href="#timeout" id="id16">timeout</a></li>
<li><a class="reference internal" href="#keepalive" id="id17">keepalive</a></li>
</ul>
</li>
<li><a class="reference internal" href="#debugging" id="id18">Debugging</a><ul>
<li><a class="reference internal" href="#debug" id="id19">debug</a></li>
<li><a class="reference internal" href="#spew" id="id20">spew</a></li>
</ul>
</li>
<li><a class="reference internal" href="#server-mechanics" id="id21">Server Mechanics</a><ul>
<li><a class="reference internal" href="#daemon" id="id22">daemon</a></li>
<li><a class="reference internal" href="#pidfile" id="id23">pidfile</a></li>
<li><a class="reference internal" href="#user" id="id24">user</a></li>
<li><a class="reference internal" href="#group" id="id25">group</a></li>
<li><a class="reference internal" href="#umask" id="id26">umask</a></li>
<li><a class="reference internal" href="#tmp-upload-dir" id="id27">tmp_upload_dir</a></li>
</ul>
</li>
<li><a class="reference internal" href="#logging" id="id28">Logging</a><ul>
<li><a class="reference internal" href="#logfile" id="id29">logfile</a></li>
<li><a class="reference internal" href="#loglevel" id="id30">loglevel</a></li>
</ul>
</li>
<li><a class="reference internal" href="#process-naming" id="id31">Process Naming</a><ul>
<li><a class="reference internal" href="#proc-name" id="id32">proc_name</a></li>
<li><a class="reference internal" href="#default-proc-name" id="id33">default_proc_name</a></li>
</ul>
</li>
<li><a class="reference internal" href="#server-hooks" id="id34">Server Hooks</a><ul>
<li><a class="reference internal" href="#pre-fork" id="id35">pre_fork</a></li>
<li><a class="reference internal" href="#post-fork" id="id36">post_fork</a></li>
<li><a class="reference internal" href="#pre-exec" id="id37">pre_exec</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="overview">
<h2><a class="toc-backref" href="#contents">Overview</a></h2>
<p>Gunicorn pulls configuration information from three distinct places.</p>
<p>The first place that Gunicorn will read configuration from is the framework
specific configuration file. Currently this only affects Paster applications.</p>
<p>The second source of configuration information is a configuration file that is
optionally specified on the command line. Anything specified in the Gunicorn
config file will override any framework specific settings.</p>
<p>Lastly, the command line arguments used to invoke Gunicorn are the final place
considered for configuration settings. If an option is specified on the command
line, this is the value that will be used.</p>
<dl class="docutils">
<dt>Once again, in order of least to most authoritative:</dt>
<dd><ol class="first last arabic simple">
<li>Framework Settings</li>
<li>Configuration File</li>
<li>Command Line</li>
</ol>
</dd>
</dl>
</div>
<div class="section" id="framework-settings">
<h2><a class="toc-backref" href="#contents">Framework Settings</a></h2>
<p>Currently, only Paster applications have access to framework specific
settings. If you have ideas for providing settings to WSGI applications or
pulling information from Django's settings.py feel free to open an <a class="reference external" href="http://github.com/benoitc/gunicorn/issues">issue</a> to
let us know.</p>
<div class="section" id="paster-applications">
<h3><a class="toc-backref" href="#contents">Paster Applications</a></h3>
<p>In your INI file, you can specify to use Gunicorn as the server like such:</p>
<pre class="literal-block">
[server:main]
use = egg:gunicorn#main
host = 192.168.0.1
port = 80
workers = 2
proc_name = brim
</pre>
<p>Any parameters that Gunicorn knows about will automatically be inserted into
the base configuration. Remember that these will be overridden by the config
file and/or the command line.</p>
</div>
</div>
<div class="section" id="configuration-file">
<h2><a class="toc-backref" href="#contents">Configuration File</a></h2>
<p>The configuration file should be a valid Python source file. It only needs to
be readable from the file system. More specifically, it does not need to be
importable. Any Python is valid. Just consider that this will be run every time
you start Gunicorn (including when you signal Gunicorn to reload).</p>
<p>To set a parameter, just assign to it. There's no special syntax. The values
you provide will be used for the configuration values.</p>
<p>For instance:</p>
<pre class="literal-block">
import os
def numCPUs():
if not hasattr(os, &quot;sysconf&quot;):
raise RuntimeError(&quot;No sysconf detected.&quot;)
return os.sysconf(&quot;SC_NPROCESSORS_ONLN&quot;)
bind = &quot;127.0.0.1:8000&quot;
workers = numCPUs() * 2 + 1
</pre>
</div>
<div class="section" id="command-line">
<h2><a class="toc-backref" href="#contents">Command Line</a></h2>
<p>If an option is specified on the command line, it overrides all other values
that may have been specified in the app specific settings, or in the optional
configuration file. Not all Gunicorn settings are available to be set from the
command line. To see the full list of command line settings you can do the
usual:</p>
<pre class="literal-block">
$ gunicorn -h
</pre>
<p>There is also a <tt class="docutils literal"><span class="pre">--version</span></tt> flag available to the command line scripts that
isn't mentioned in the list of settings.</p>
</div>
<div class="section" id="settings">
<h2><a class="toc-backref" href="#contents">Settings</a></h2>
<p>This is an exhaustive list of settings for Gunicorn. Some settings are only
able to be set from a configuration file. The setting name is what should be
used in the configuration file. The command line arguments are listed as well
for reference on setting at the command line.</p>
<div class="section" id="config-file">
<h3><a class="toc-backref" href="#contents">Config File</a></h3>
<div class="section" id="config">
<h4><a class="toc-backref" href="#contents">config</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-c</span> FILE, <span class="pre">--config</span> FILE</tt></li>
<li><tt class="docutils literal">None</tt></li>
</ul>
<p>The path to a Gunicorn config file.</p>
<p>Only has an effect when specified on the command line or as part of an
application specific configuration.</p>
</div>
</div>
<div class="section" id="server-socket">
<h3><a class="toc-backref" href="#contents">Server Socket</a></h3>
<div class="section" id="bind">
<h4><a class="toc-backref" href="#contents">bind</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-b</span> ADDRESS, <span class="pre">--bind</span> ADDRESS</tt></li>
<li><tt class="docutils literal">127.0.0.1:8000</tt></li>
</ul>
<p>The socket to bind.</p>
<p>A string of the form: 'HOST', 'HOST:PORT', 'unix:PATH'. An IP is a valid
HOST.</p>
</div>
<div class="section" id="backlog">
<h4><a class="toc-backref" href="#contents">backlog</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">--backlog</span> INT</tt></li>
<li><tt class="docutils literal">2048</tt></li>
</ul>
<p>The maximum number of pending connections.</p>
<p>This refers to the number of clients that can be waiting to be served.
Exceeding this number results in the client getting an error when
attempting to connect. It should only affect servers under significant
load.</p>
<p>Must be a positive integer. Generally set in the 64-2048 range.</p>
</div>
</div>
<div class="section" id="worker-processes">
<h3><a class="toc-backref" href="#contents">Worker Processes</a></h3>
<div class="section" id="workers">
<h4><a class="toc-backref" href="#contents">workers</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-w</span> INT, <span class="pre">--workers</span> INT</tt></li>
<li><tt class="docutils literal">1</tt></li>
</ul>
<p>The number of worker process for handling requests.</p>
<p>A positive integer generally in the 2-4 x $(NUM_CORES) range. You'll
want to vary this a bit to find the best for your particular
application's work load.</p>
</div>
<div class="section" id="worker-class">
<h4><a class="toc-backref" href="#contents">worker_class</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-k</span> STRING, <span class="pre">--worker-class</span> STRING</tt></li>
<li><tt class="docutils literal">egg:gunicorn#sync</tt></li>
</ul>
<p>The type of workers to use.</p>
<p>The default async class should handle most 'normal' types of work loads.
You'll want to read <a class="reference external" href="http://gunicorn.org/design.hml">http://gunicorn.org/design.hml</a> for information on
when you might want to choose one of the other worker classes.</p>
<p>An string referring to a 'gunicorn.workers' entry point or a
MODULE:CLASS pair where CLASS is a subclass of
gunicorn.workers.base.Worker.</p>
<p>The default provided values are:</p>
<ul class="simple">
<li><tt class="docutils literal">egg:gunicorn#sync</tt></li>
<li><tt class="docutils literal">egg:gunicorn#eventlet</tt> - Requires eventlet &gt;= 0.9.7</li>
<li><tt class="docutils literal">egg:gunicorn#gevent</tt> - Requires gevent &gt;= 0.12.2 (?)</li>
<li><tt class="docutils literal">egg:gunicorn#tornado</tt> - Requires tornado &gt;= 0.2</li>
</ul>
</div>
<div class="section" id="worker-connections">
<h4><a class="toc-backref" href="#contents">worker_connections</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">--worker-connections</span> INT</tt></li>
<li><tt class="docutils literal">1000</tt></li>
</ul>
<p>The maximum number of simultaneous clients.</p>
<p>This setting only affects the Eventlet and Gevent worker types.</p>
</div>
<div class="section" id="timeout">
<h4><a class="toc-backref" href="#contents">timeout</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-t</span> INT, <span class="pre">--timeout</span> INT</tt></li>
<li><tt class="docutils literal">30</tt></li>
</ul>
<p>Workers silent for more than this many seconds are killed and restarted.</p>
<p>Generally set to thirty seconds. Only set this noticeably higher if
you're sure of the repercussions for sync workers. For the non sync
workers it just means that the worker process is still communicating and
is not tied to the length of time required to handle a single request.</p>
</div>
<div class="section" id="keepalive">
<h4><a class="toc-backref" href="#contents">keepalive</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">--keep-alive</span> INT</tt></li>
<li><tt class="docutils literal">2</tt></li>
</ul>
<p>The number of seconds to wait for requests on a Keep-Alive connection.</p>
<p>Generally set in the 1-5 seconds range.</p>
</div>
</div>
<div class="section" id="debugging">
<h3><a class="toc-backref" href="#contents">Debugging</a></h3>
<div class="section" id="debug">
<h4><a class="toc-backref" href="#contents">debug</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-d,</span> <span class="pre">--debug</span></tt></li>
<li><tt class="docutils literal">False</tt></li>
</ul>
<p>Turn on debugging in the server.</p>
<p>This limits the number of worker processes to 1 and changes some error
handling that's sent to clients.</p>
</div>
<div class="section" id="spew">
<h4><a class="toc-backref" href="#contents">spew</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">--spew</span></tt></li>
<li><tt class="docutils literal">False</tt></li>
</ul>
<p>Install a trace function that spews every line executed by the server.</p>
<p>This is the nuclear option.</p>
</div>
</div>
<div class="section" id="server-mechanics">
<h3><a class="toc-backref" href="#contents">Server Mechanics</a></h3>
<div class="section" id="daemon">
<h4><a class="toc-backref" href="#contents">daemon</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-D,</span> <span class="pre">--daemon</span></tt></li>
<li><tt class="docutils literal">False</tt></li>
</ul>
<p>Daemonize the Gunicorn process.</p>
<p>Detaches the server from the controlling terminal and enters the
background.</p>
</div>
<div class="section" id="pidfile">
<h4><a class="toc-backref" href="#contents">pidfile</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-p</span> FILE, <span class="pre">--pid</span> FILE</tt></li>
<li><tt class="docutils literal">None</tt></li>
</ul>
<p>A filename to use for the PID file.</p>
<p>If not set, no PID file will be written.</p>
</div>
<div class="section" id="user">
<h4><a class="toc-backref" href="#contents">user</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-u</span> USER, <span class="pre">--user</span> USER</tt></li>
<li><tt class="docutils literal">None</tt></li>
</ul>
<p>Switch worker processes to run as this user.</p>
<p>A valid user id (as an integer) or the name of a user that can be
retrieved with a call to pwd.getpwnam(value) or None to not change
the worker process user.</p>
</div>
<div class="section" id="group">
<h4><a class="toc-backref" href="#contents">group</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-g</span> GROUP, <span class="pre">--group</span> GROUP</tt></li>
<li><tt class="docutils literal">None</tt></li>
</ul>
<p>Switch worker process to run as this group.</p>
<p>A valid group id (as an integer) or the name of a user that can be
retrieved with a call to pwd.getgrnam(value) or None to not change
the worker processes group.</p>
</div>
<div class="section" id="umask">
<h4><a class="toc-backref" href="#contents">umask</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-m</span> INT, <span class="pre">--umask</span> INT</tt></li>
<li><tt class="docutils literal">0</tt></li>
</ul>
<p>A bit mask for the file mode on files written by Gunicorn.</p>
<p>Note that this affects unix socket permissions.</p>
<p>A valid value for the os.umask(mode) call or a string compatible with
int(value, 0) (0 means Python guesses the base, so values like &quot;0&quot;,
&quot;0xFF&quot;, &quot;0022&quot; are valid for decimal, hex, and octal representations)</p>
</div>
<div class="section" id="tmp-upload-dir">
<h4><a class="toc-backref" href="#contents">tmp_upload_dir</a></h4>
<ul class="simple">
<li><tt class="docutils literal">None</tt></li>
</ul>
<p>Directory to store temporary request data as they are read.</p>
<p>This may disappear in the near future.</p>
<p>This path should be writable by the process permissions set for Gunicorn
workers. If not specified, Gunicorn will choose a system generated
temporary directory.</p>
</div>
</div>
<div class="section" id="logging">
<h3><a class="toc-backref" href="#contents">Logging</a></h3>
<div class="section" id="logfile">
<h4><a class="toc-backref" href="#contents">logfile</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">--log-file</span> FILE</tt></li>
<li><tt class="docutils literal">-</tt></li>
</ul>
<p>The log file to write to.</p>
<p>&quot;-&quot; means log to stdout.</p>
</div>
<div class="section" id="loglevel">
<h4><a class="toc-backref" href="#contents">loglevel</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">--log-level</span> LEVEL</tt></li>
<li><tt class="docutils literal">info</tt></li>
</ul>
<p>The granularity of log output</p>
<p>Valid level names are:</p>
<ul class="simple">
<li>debug</li>
<li>info</li>
<li>warning</li>
<li>error</li>
<li>critical</li>
</ul>
</div>
</div>
<div class="section" id="process-naming">
<h3><a class="toc-backref" href="#contents">Process Naming</a></h3>
<div class="section" id="proc-name">
<h4><a class="toc-backref" href="#contents">proc_name</a></h4>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-n</span> STRING, <span class="pre">--name</span> STRING</tt></li>
<li><tt class="docutils literal">gunicorn</tt></li>
</ul>
<p>A base to use with setproctitle for process naming.</p>
<p>This affects things like <tt class="docutils literal">ps</tt> and <tt class="docutils literal">top</tt>. If you're going to be
running more than one instance of Gunicorn you'll probably want to set a
name to tell them apart. This requires that you install the setproctitle
module.</p>
<p>It defaults to 'gunicorn'.</p>
</div>
<div class="section" id="default-proc-name">
<h4><a class="toc-backref" href="#contents">default_proc_name</a></h4>
<ul class="simple">
<li><tt class="docutils literal">gunicorn</tt></li>
</ul>
<p>Internal setting that is adjusted for each type of application.</p>
</div>
</div>
<div class="section" id="server-hooks">
<h3><a class="toc-backref" href="#contents">Server Hooks</a></h3>
<div class="section" id="pre-fork">
<h4><a class="toc-backref" href="#contents">pre_fork</a></h4>
<ul>
<li><pre class="first literal-block">
def def_pre_fork(server, worker):
pass
</pre>
</li>
</ul>
<p>Called just before a worker is forked.</p>
<p>The callable needs to accept two instance variables for the Arbiter and
new Worker.</p>
</div>
<div class="section" id="post-fork">
<h4><a class="toc-backref" href="#contents">post_fork</a></h4>
<ul>
<li><pre class="first literal-block">
def def_post_fork(server, worker):
server.log.info(&quot;Worker spawned (pid: %s)&quot; % worker.pid)
</pre>
</li>
</ul>
<p>Called just after a worker has been forked.</p>
<p>The callable needs to accept two instance variables for the Arbiter and
new Worker.</p>
</div>
<div class="section" id="pre-exec">
<h4><a class="toc-backref" href="#contents">pre_exec</a></h4>
<ul>
<li><pre class="first literal-block">
def def_pre_exec(server):
server.log.info(&quot;Forked child, reexecuting.&quot;)
</pre>
</li>
</ul>
<p>Called just before a new master process is forked.</p>
<p>The callable needs to accept a single instance variable for the Arbiter.</p>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</body>
</html>

View File

@ -58,10 +58,208 @@ a img {
border: none;
}
/* line 6, ../../css/style.sass */
/* line 25, ../../css/style.sass */
body {
background: #f9f9f9;
color: #2a2a2a;
line-height: 18px;
font-family: Arial, sans-serif;
font-size: 13px;
}
/* line 32, ../../css/style.sass */
div.container {
display: block;
width: 700px;
margin: 0 auto;
}
/* line 37, ../../css/style.sass */
#header {
margin: 1em auto;
text-align: center;
}
/* line 41, ../../css/style.sass */
#menu {
width: 100%;
margin: 1em 0;
border-bottom: 1px solid #bbbbbb;
text-align: center;
}
/* line 46, ../../css/style.sass */
#menu ul {
list-style: none;
display: inline;
}
/* line 11, ../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.10.1/frameworks/compass/stylesheets/compass/utilities/lists/_bullets.scss */
#menu ul li {
list-style-image: none;
list-style-type: none;
margin-left: 0px;
}
/* line 49, ../../css/style.sass */
#menu ul li {
display: inline;
margin-right: 15px;
text-align: center;
}
/* line 53, ../../css/style.sass */
#menu ul li a {
font-size: 20px;
font-weight: 700;
color: #489848;
text-decoration: none;
}
/* line 59, ../../css/style.sass */
#contents.sidebar {
float: right;
width: 150px;
}
/* line 62, ../../css/style.sass */
#contents.sidebar ul {
margin-bottom: 0.2em;
}
/* line 65, ../../css/style.sass */
p.topic-title {
display: none;
}
/* line 68, ../../css/style.sass */
div.section {
margin-right: 170px;
}
/* line 71, ../../css/style.sass */
div.section div.section {
margin-right: 0;
}
/* line 74, ../../css/style.sass */
div.section ul {
margin-left: 15px;
list-style: none;
}
/* line 11, ../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.10.1/frameworks/compass/stylesheets/compass/utilities/lists/_bullets.scss */
div.section ul li {
list-style-image: none;
list-style-type: none;
margin-left: 0px;
}
/* line 78, ../../css/style.sass */
h1, h2, h3, h4 {
color: #489848;
}
/* line 81, ../../css/style.sass */
h1 {
margin-top: 10px;
font-size: 26px;
}
/* line 85, ../../css/style.sass */
h2 {
border-bottom: 5px solid #cccccc;
margin-bottom: 13px;
padding-bottom: 3px;
font-size: 20px;
font-weight: 700;
}
/* line 92, ../../css/style.sass */
h3 {
border-bottom: 1px solid #cccccc;
margin-bottom: 13px;
font-weight: 700;
}
/* line 97, ../../css/style.sass */
a {
color: #569633;
text-decoration: none;
}
/* line 101, ../../css/style.sass */
p {
margin-bottom: 1em;
font-size: 1em;
}
/* line 105, ../../css/style.sass */
ol {
list-style: decimal;
margin-left: 2em;
margin-bottom: 13px;
}
/* line 110, ../../css/style.sass */
ul {
list-style: disc;
margin-left: 2em;
margin-bottom: 13px;
}
/* line 115, ../../css/style.sass */
pre, tt {
font-family: "andale mono", "lucida console", monospace;
font-size: 12px;
background: #ffffdd;
}
/* line 120, ../../css/style.sass */
pre {
white-space: pre;
margin: 3px 3px 2em 3px;
padding: 8px 20px;
}
/* line 125, ../../css/style.sass */
.note {
border-top: 1px solid #489848;
border-bottom: 1px solid #489848;
padding: 0.6em 0.6em 0.6em 80px;
margin-bottom: 2em;
position: relative;
}
/* line 131, ../../css/style.sass */
.note p.admonition-title:before {
content: "!";
font-size: 60px;
font-weight: bold;
color: #489848;
position: absolute;
top: 30px;
left: 30px;
font-family: helvetica, arial;
}
/* line 140, ../../css/style.sass */
.note p.admonition-title {
font-weight: 700;
margin: 0;
margin-bottom: 4px;
padding: 0;
}
/* line 145, ../../css/style.sass */
.note p.last {
padding: 0;
margin: 0;
}
/* line 149, ../../css/style.sass */
#footer {
border-top: 1px solid #cccccc;
clear: both;
display: block;
width: 100%;
margin-top: 3em;
padding-top: 1em;
text-align: center;
font-size: 0.8em;
}
/* line 158, ../../css/style.sass */
#footer a {
color: #444444;
}

194
doc/htdocs/deploy.html Normal file
View File

@ -0,0 +1,194 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Green Unicorn - Deploy</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
<div class="document">
<div class="contents sidebar topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#nginx-configuration" id="id3">Nginx Configuration</a></li>
<li><a class="reference internal" href="#using-virtualenv" id="id4">Using Virtualenv</a></li>
<li><a class="reference internal" href="#monitoring" id="id5">Monitoring</a><ul>
<li><a class="reference internal" href="#runit" id="id6">Runit</a></li>
<li><a class="reference internal" href="#supervisor" id="id7">Supervisor</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="nginx-configuration">
<h2><a class="toc-backref" href="#contents">Nginx Configuration</a></h2>
<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 workers. 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;
user nobody nogroup;
pid /tmp/nginx.pid;
error_log /tmp/nginx.error.log;
events {
worker_connections 1024;
accept_mutex off;
}
http {
include mime.types;
default_type application/octet-stream;
access_log /tmp/nginx.access.log combined;
sendfile on;
upstream app_server {
server unix:/tmp/gunicorn.sock fail_timeout=0;
# For a TCP configuration:
# server 192.168.0.7:8000 fail_timeout=0;
}
server {
listen 80 default;
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
# path for static files
root /path/to/app/current/public;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://app_server;
break;
}
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /path/to/app/current/public;
}
}
}
</pre>
<p>If you want to be able to handle streaming request/responses or other fancy
features like Comet, Long polling, or Web sockets, you need to turn off the
proxy buffering. <strong>When you do this</strong> you must run with one of the async worker
classes.</p>
<p>To turn off buffering, you only need to add <tt class="docutils literal">proxy_buffering off;</tt> to your
<tt class="docutils literal">location</tt> block:</p>
<pre class="literal-block">
...
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_buffering off;
if (!-f $request_filename) {
proxy_pass http://app_server;
break;
}
}
...
</pre>
</div>
<div class="section" id="using-virtualenv">
<h2><a class="toc-backref" href="#contents">Using Virtualenv</a></h2>
<p>To serve an app from a <a class="reference external" href="http://pypi.python.org/pypi/virtualenv">Virtualenv</a> it is generally easiest to just install
Gunicorn directly into the Virtualenv. This will create a set of Gunicorn
scripts for that Virtualenv which can be used to run applications normally.</p>
<p>If you have Virtualenv installed, you should be able to do something like
this:</p>
<pre class="literal-block">
$ mkdir ~/venvs/
$ virtualenv ~/venvs/webapp
$ source ~/venvs/webapp/bin/activate
$ ~/venvs/webapp/bin/easy_install -U gunicorn
$ deactivate
</pre>
<p>Then you just need to use one of the three Gunicorn scripts that was installed
into <tt class="docutils literal">~/venvs/webapp/bin</tt>.</p>
</div>
<div class="section" id="monitoring">
<h2><a class="toc-backref" href="#contents">Monitoring</a></h2>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">Make sure that when using either of these service monitors you do not
enable the Gunicorn's daemon mode. These monitors expect that the process
they launch will be the process they need to monior. Daemonizing
will fork-exec which creates an unmonitored process and generally just
confuses the monitor services.</p>
</div>
<div class="section" id="runit">
<h3><a class="toc-backref" href="#contents">Runit</a></h3>
<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
GUNICORN=/usr/local/bin/gunicorn
ROOT=/path/to/project
PID=/var/run/gunicorn.pid
APP=main:application
if [ -f $PID ]; then rm $PID fi
cd $ROOT
exec $GUNICORN -C $ROOT/gunicorn.conf.py --pidfile=$PID $APP
</pre>
</div>
<div class="section" id="supervisor">
<h3><a class="toc-backref" href="#contents">Supervisor</a></h3>
<p>Another useful tool to monitor and control Gunicorn is <a class="reference external" href="http://supervisord.org">Supervisor</a>. A
<a class="reference external" href="http://github.com/benoitc/gunicorn/blob/master/examples/supervisor.conf">simple configuration</a> is:</p>
<pre class="literal-block">
[program:gunicorn]
command=/usr/local/bin/gunicorn main:application -c /path/to/project/gunicorn.conf.py
directory=/path/to/project
user=nobody
autostart=true
autorestart=true
redirect_stderr=True
</pre>
</div>
</div>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</body>
</html>

View File

@ -4,53 +4,28 @@
<meta charset="utf-8" />
<title>Green Unicorn - Deployment</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<!--[if IE]>
<script>
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('nav');
document.createElement('time');
</script>
<![endif]-->
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div id="links">
Get the source via
<a href="http://github.com/benoitc/gunicorn">git</a>, then
<a href="http://github.com/benoitc/gunicorn/issues">send feedback</a>
</div>
</div>
<div id="menu">
<ul id="actions">
<li><a href="installation.html">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="deployment.html">Deployment</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="tuning.html">Tuning</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="production-setup">
<div class="container">
<div id="header">
<a href="http://gunicorn.org">
<img src="/images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="production-setup">
<h1 class="title">Production Setup</h1>
<div class="section" id="synchronous-vs-asynchronous-workers">
<h1>Synchronous vs Asynchronous workers</h1>
<h2>Synchronous vs Asynchronous workers</h2>
<p>The default configuration of Gunicorn assumes that your application code is
mostly CPU bound. The default worker class is a simple single threaded loop that
just processes requests as they are received. In general, most applications will
@ -72,7 +47,7 @@ of free worker processes (because they're all stuck waiting for data).</p>
</blockquote>
</div>
<div class="section" id="basic-nginx-configuration">
<h1>Basic Nginx Configuration</h1>
<h2>Basic Nginx Configuration</h2>
<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 workers. Without this
@ -154,7 +129,7 @@ location / {
</pre>
</div>
<div class="section" id="working-with-virtualenv">
<h1>Working with Virtualenv</h1>
<h2>Working with Virtualenv</h2>
<p>To serve an app from a <a class="reference external" href="http://pypi.python.org/pypi/virtualenv">Virtualenv</a> it is generally easiest to just install
Gunicorn directly into the Virtualenv. This will create a set of Gunicorn
scripts for that Virtualenv which can be used to run applications normally.</p>
@ -171,7 +146,7 @@ $ deactivate
into <tt class="docutils literal">~/venvs/webapp/bin</tt>.</p>
</div>
<div class="section" id="daemon-monitoring">
<h1>Daemon Monitoring</h1>
<h2>Daemon Monitoring</h2>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">Make sure that when using either of these service monitors you do not
@ -210,12 +185,10 @@ redirect_stderr=True
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</div>
</body>
</html>

128
doc/htdocs/design.html Normal file
View File

@ -0,0 +1,128 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Green Unicorn - Design</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
<div class="document">
<div class="contents sidebar topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#server-model" id="id1">Server Model</a><ul>
<li><a class="reference internal" href="#master" id="id2">Master</a></li>
<li><a class="reference internal" href="#sync-workers" id="id3">Sync Workers</a></li>
<li><a class="reference internal" href="#async-workers" id="id4">Async Workers</a></li>
<li><a class="reference internal" href="#tornado-workers" id="id5">Tornado Workers</a></li>
</ul>
</li>
<li><a class="reference internal" href="#choosing-a-worker-type" id="id6">Choosing a Worker Type</a></li>
<li><a class="reference internal" href="#how-many-workers" id="id7">How Many Workers?</a></li>
</ul>
</div>
<div class="section" id="server-model">
<h2><a class="toc-backref" href="#contents">Server Model</a></h2>
<p>Gunicorn is based on the pre-fork worker model. This means that there is a
central master process that manages a set of worker processes. The master
never knows anything about individual clients. All requests and responses are
handled completely by worker processes.</p>
<div class="section" id="master">
<h3><a class="toc-backref" href="#contents">Master</a></h3>
<p>The master process is a simple loop that listens for various process signals
and reacts accordingly. It manages the list of running workers by listening
for signals like TTIN, TTOU, and CHLD. TTIN and TTOU tell the master to
increase or decrease the number of running workers. CHLD indicates that a child
process has terminated, in this case the master process automatically restarts
the failed worker.</p>
</div>
<div class="section" id="sync-workers">
<h3><a class="toc-backref" href="#contents">Sync Workers</a></h3>
<p>The most basic and the default worker type is a synchronous worker class that
handles a single request at a time. This model is the simplest to reason about
as any errors will affect at most a single request. Though as we describe below
only processing a single request at a time requires some assumptions about how
applications are programmed.</p>
</div>
<div class="section" id="async-workers">
<h3><a class="toc-backref" href="#contents">Async Workers</a></h3>
<p>The asynchronous workers available are based on <a class="reference external" href="http://bitbucket.org/ambroff/greenlet">Greenlets</a> (via <a class="reference external" href="http://eventlet.net">Eventlet</a> and
<a class="reference external" href="http://gevent.org">Gevent</a>). Greenlets are an implementation of cooperative multi-threading for
Python. In general, an application should be able to make use of these worker
classes with no changes.</p>
</div>
<div class="section" id="tornado-workers">
<h3><a class="toc-backref" href="#contents">Tornado Workers</a></h3>
<p>There's also a Tornado worker class. It can be used to write applications using
the Tornado framework. Although the Tornado workers are capable of serving a
WSGI application, this is not a recommended configuration.</p>
</div>
</div>
<div class="section" id="choosing-a-worker-type">
<h2><a class="toc-backref" href="#contents">Choosing a Worker Type</a></h2>
<p>The default synchronous workers assume that your application is resource bound
in terms of CPU and network bandwidth. Generally this means that your
application shouldn't do anything that takes an undefined amount of time. For
instance, a request to the internet meets this criteria. At some point the
external network will fail in such a way that clients will pile up on your
servers.</p>
<p>This resource bound assumption is why we require a buffering proxy in front of a
default configuration Gunicorn. If you exposed synchronous workers to the
internet, a DOS attack would be trivial by creating a load that trickles data to
the servers. For the curious, <a class="reference external" href="http://ha.ckers.org/slowloris/">Slowloris</a> is an example of this type of load.</p>
<p>Some examples of behavior requiring asynchronous workers:</p>
<blockquote>
<ul class="simple">
<li>Applications making long blocking calls (Ie, external web services)</li>
<li>Serving requests directly to the internet</li>
<li>Streaming requests and responses</li>
<li>Long polling</li>
<li>Web sockets</li>
<li>Comet</li>
</ul>
</blockquote>
</div>
<div class="section" id="how-many-workers">
<h2><a class="toc-backref" href="#contents">How Many Workers?</a></h2>
<p>Gunicorn relies on the operating system to provide all of the load balancing
when handling requests. Generally we recommend <tt class="docutils literal">(2 x $num_cores) + 1</tt> as the
number of workers to start off with. While not overly scientific, the formula
is based on the assumption that for a given core, one worker will be reading
or writing from the socket while the other worker is processing a request.</p>
<p>Obviously, your particular hardware and application are going to affect what
the optimal number of workers is. Our recommendation is to start with the above
guess and tune using TTIN and TTOU signals while the application is under load.</p>
<p>Always remember, there is such a thing as too many workers. After a point your
worker processes will start thrashing system resources decreasing the throughput
of the entire system.</p>
</div>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</body>
</html>

View File

@ -4,104 +4,117 @@
<meta charset="utf-8" />
<title>Green Unicorn - FAQ</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<!--[if IE]>
<script>
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('nav');
document.createElement('time');
</script>
<![endif]-->
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div id="links">
Get the source via
<a href="http://github.com/benoitc/gunicorn">git</a>, then
<a href="http://github.com/benoitc/gunicorn/issues">send feedback</a>
</div>
</div>
<div id="menu">
<ul id="actions">
<li><a href="installation.html">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="deployment.html">Deployment</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="tuning.html">Tuning</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="faq">
<h1 class="title">FAQ</h1>
<dl class="docutils">
<dt>How do I know which type of worker to use?</dt>
<dd>Test. Read the &quot;Synchronous vs Asynchronous workers&quot; section on the
<a class="reference external" href="http://gunicorn.org/deployment.html">deployment</a> page. Test some more.</dd>
<dt>What types of workers are there?</dt>
<dd><p class="first">These can all be used with the <tt class="docutils literal"><span class="pre">-k</span></tt> option and specifying them
as <tt class="docutils literal"><span class="pre">egg:gunicorn#$(NAME)</span></tt> where <tt class="docutils literal">$(NAME)</tt> is chosen from this list.</p>
<ul class="last simple">
<li><tt class="docutils literal">sync</tt> - The default synchronous worker</li>
<li><tt class="docutils literal">eventlet</tt> - Asynchronous workers based on Greenlets</li>
<li><tt class="docutils literal">gevent</tt> - Asynchronous workers based on Greenlets</li>
<li><tt class="docutils literal">tornado</tt> - Asynchronous workers based on FriendFeed's Tornado server.</li>
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
<div class="document">
<div class="contents topic" id="questions">
<p class="topic-title first">Questions</p>
<ul class="simple">
<li><a class="reference internal" href="#wsgi-bits" id="id1">WSGI Bits</a><ul>
<li><a class="reference internal" href="#how-do-i-set-script-name" id="id2">How do I set SCRIPT_NAME?</a></li>
</ul>
</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
should be comfortable that all is well with your configuration.</dd>
<dt>How do I reload my application in Gunicorn?</dt>
<dd><p class="first">You can gracefully reload by sending HUP signal to gunicorn:</p>
<pre class="last literal-block">
</li>
<li><a class="reference internal" href="#server-stuff" id="id3">Server Stuff</a><ul>
<li><a class="reference internal" href="#how-do-i-reload-my-application-in-gunicorn" id="id4">How do I reload my application in Gunicorn?</a></li>
<li><a class="reference internal" href="#how-might-i-test-a-proxy-configuration" id="id5">How might I test a proxy configuration?</a></li>
<li><a class="reference internal" href="#how-can-i-name-processes" id="id6">How can I name processes?</a></li>
</ul>
</li>
<li><a class="reference internal" href="#worker-processes" id="id7">Worker Processes</a><ul>
<li><a class="reference internal" href="#how-do-i-know-which-type-of-worker-to-use" id="id8">How do I know which type of worker to use?</a></li>
<li><a class="reference internal" href="#what-types-of-workers-are-there" id="id9">What types of workers are there?</a></li>
<li><a class="reference internal" href="#how-can-i-figure-out-the-best-number-of-worker-processes" id="id10">How can I figure out the best number of worker processes?</a></li>
<li><a class="reference internal" href="#how-can-i-change-the-number-of-workers-dynamically" id="id11">How can I change the number of workers dynamically?</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="wsgi-bits">
<h2><a class="toc-backref" href="#questions">WSGI Bits</a></h2>
<div class="section" id="how-do-i-set-script-name">
<h3><a class="toc-backref" href="#questions">How do I set SCRIPT_NAME?</a></h3>
<p>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.</p>
</div>
</div>
<div class="section" id="server-stuff">
<h2><a class="toc-backref" href="#questions">Server Stuff</a></h2>
<div class="section" id="how-do-i-reload-my-application-in-gunicorn">
<h3><a class="toc-backref" href="#questions">How do I reload my application in Gunicorn?</a></h3>
<p>You can gracefully reload by sending HUP signal to gunicorn:</p>
<pre class="literal-block">
$ kill -HUP masterpid
</pre>
</dd>
<dt>How do I increase or decrease the number of running workers dynamically?</dt>
<dd><p class="first">To increase the worker count by one:</p>
</div>
<div class="section" id="how-might-i-test-a-proxy-configuration">
<h3><a class="toc-backref" href="#questions">How might I test a proxy configuration?</a></h3>
<p>The <a class="reference external" href="http://ha.ckers.org/slowloris/">Slowloris</a> script is a great way to test that your proxy is correctly
buffering responses for the synchronous workers.</p>
</div>
<div class="section" id="how-can-i-name-processes">
<h3><a class="toc-backref" href="#questions">How can I name processes?</a></h3>
<p>If you install the Python package <a class="reference external" href="http://pypi.python.org/pypi/setproctitle">setproctitle</a> Gunicorn will set the process
names to something a bit more meaningful. This will affect the output you see
in tools like <tt class="docutils literal">ps</tt> and <tt class="docutils literal">top</tt>. This helps for distinguishing the master
process as well as between masters when running more than one app on a single
machine. See the <a class="reference external" href="/configure.html#proc-name">proc_name</a> setting for more information.</p>
</div>
</div>
<div class="section" id="worker-processes">
<h2><a class="toc-backref" href="#questions">Worker Processes</a></h2>
<div class="section" id="how-do-i-know-which-type-of-worker-to-use">
<h3><a class="toc-backref" href="#questions">How do I know which type of worker to use?</a></h3>
<p>Read the <a class="reference external" href="/design.html">design</a> page for help on the various worker types.</p>
</div>
<div class="section" id="what-types-of-workers-are-there">
<h3><a class="toc-backref" href="#questions">What types of workers are there?</a></h3>
<p>Check out the configuration docs for <a class="reference external" href="/configure.html#worker-class">worker_class</a></p>
</div>
<div class="section" id="how-can-i-figure-out-the-best-number-of-worker-processes">
<h3><a class="toc-backref" href="#questions">How can I figure out the best number of worker processes?</a></h3>
<p>Here is our recommendation for tuning the <a class="reference external" href="/design.html#how-many-workers">number of workers</a>.</p>
</div>
<div class="section" id="how-can-i-change-the-number-of-workers-dynamically">
<h3><a class="toc-backref" href="#questions">How can I change the number of workers dynamically?</a></h3>
<blockquote>
<p>To increase the worker count by one:</p>
<pre class="literal-block">
$ kill -TTIN $masterpid
</pre>
<p>To decrease the worker count by one:</p>
<pre class="last literal-block">
<pre class="literal-block">
$ kill -TTOU $masterpid
</pre>
</dd>
<dt>How can I figure out the best number of worker processes?</dt>
<dd>Start gunicorn with an approximate number of worker processes. Then use the
TTIN and/or TTOU signals to adjust the number of workers under load.</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>
<dt>How can I 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 specify
a base process name on the command line (<tt class="docutils literal"><span class="pre">-n</span></tt>) or in the configuration
file.</dd>
</dl>
</blockquote>
</div>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</div>
</body>
</html>

View File

@ -4,57 +4,40 @@
<meta charset="utf-8" />
<title>Green Unicorn - Welcome</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<!--[if IE]>
<script>
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('nav');
document.createElement('time');
</script>
<![endif]-->
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div id="links">
Get the source via
<a href="http://github.com/benoitc/gunicorn">git</a>, then
<a href="http://github.com/benoitc/gunicorn/issues">send feedback</a>
</div>
</div>
<div id="menu">
<ul id="actions">
<li><a href="installation.html">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="deployment.html">Deployment</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="tuning.html">Tuning</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="green-unicorn">
<h1 class="title">Green Unicorn</h1>
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
<div class="document">
<div class="section" id="green-unicorn">
<h2>Green Unicorn</h2>
<p>Gunicorn 'Green Unicorn' is a <a class="reference external" href="http://www.python.org/dev/peps/pep-0333/">WSGI</a> HTTP Server for UNIX. It's a pre-fork
worker model ported from Ruby's <a class="reference external" href="http://unicorn.bogomips.org/">Unicorn</a> project. The Gunicorn server is
broadly compatible with various web frameworks, simply implemented, light
on server resource usage, and fairly speedy.</p>
<p>Feel free to join us in <a class="reference external" href="http://webchat.freenode.net/?channels=gunicorn">#gunicorn</a> on <a class="reference external" href="http://freenode.net">freenode</a>.</p>
<p>Gunicorn is released under the MIT License. See the <a class="reference external" href="http://github.com/benoitc/gunicorn/blob/master/LICENSE">LICENSE</a> for more details.</p>
</div>
<div class="section" id="features">
<h1>Features</h1>
<h2>Features</h2>
<ul class="simple">
<li>Designed for Unix.</li>
<li>Compatible with Python 2.x (&gt;= 2.5)</li>
@ -72,7 +55,7 @@ or stream-based protocols over HTTP</li>
</ul>
</div>
<div class="section" id="applications">
<h1>Applications</h1>
<h2>Applications</h2>
<ul class="simple">
<li>Any <a class="reference external" href="http://www.python.org/dev/peps/pep-0333/">WSGI</a>, <a class="reference external" href="http://djangoproject.com">Django</a> and <a class="reference external" href="http://pythonpaste.org/">Paster</a> compatible applications
(<a class="reference external" href="http://pylonshq.com/">Pylons</a>, <a class="reference external" href="http://turbogears.org/2.0/">TurboGears 2</a>, ...)</li>
@ -84,10 +67,11 @@ or stream-based protocols over HTTP</li>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</div>
</body>
</html>

149
doc/htdocs/install.html Normal file
View File

@ -0,0 +1,149 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Green Unicorn - Install</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
<div class="document">
<div class="contents sidebar topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#requirements" id="id1">Requirements</a></li>
<li><a class="reference internal" href="#with-easy-install" id="id2">With easy_install</a></li>
<li><a class="reference internal" href="#from-source" id="id3">From Source</a></li>
<li><a class="reference internal" href="#async-workers" id="id4">Async Workers</a></li>
<li><a class="reference internal" href="#ubuntu-debian" id="id5">Ubuntu/Debian</a><ul>
<li><a class="reference internal" href="#signing-key" id="id6">Signing key</a></li>
<li><a class="reference internal" href="#fingerprint" id="id7">Fingerprint</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="requirements">
<h2><a class="toc-backref" href="#contents">Requirements</a></h2>
<ul class="simple">
<li><strong>Python 2.x &gt;= 2.5</strong> (Python 3.x will be supported soon)</li>
<li>setuptools &gt;= 0.6c6</li>
<li>nosetests (for the test suite only)</li>
</ul>
</div>
<div class="section" id="with-easy-install">
<h2><a class="toc-backref" href="#contents">With easy_install</a></h2>
<p>If you don't already have <tt class="docutils literal">easy_install</tt> available you'll want to download
and run the <tt class="docutils literal">ez_setup.py</tt> script:</p>
<pre class="literal-block">
$ curl -O http://peak.telecommunity.com/dist/ez_setup.py
$ sudo python ez_setup.py -U setuptools
</pre>
<p>To install or upgrade to the latest released version of Gunicorn:</p>
<pre class="literal-block">
$ sudo easy_install -U gunicorn
</pre>
</div>
<div class="section" id="from-source">
<h2><a class="toc-backref" href="#contents">From Source</a></h2>
<p>You can install Gunicorn from source just as you would install any other
Python package. Gunicorn uses setuptools which will automatically fetch all
dependencies (including setuptools itself).</p>
<p>You can download a tarball of the latest sources from <a class="reference external" href="http://github.com/benoitc/gunicorn/downloads">GitHub Downloads</a> or
fetch them with <a class="reference external" href="http://git-scm.com/">git</a>:</p>
<pre class="literal-block">
# Using git:
$ git clone git://github.com/benoitc/gunicorn.git
$ cd gunicorn
# Or using a tarball:
$ wget http://github.com/benoitc/gunicorn/tarball/master -o gunicorn.tar.gz
$ tar -xvzf gunicorn.tar.gz
$ cd gunicorn-$HASH/
# Install
$ sudo python setup.py install
</pre>
<p>If you've cloned the git repository, its highly recommended that you use the
<tt class="docutils literal">develop</tt> command which will allow you to use Gunicorn from the source
directory. This will allow you to keep up to date with development on GitHub as
well as make changes to the source:</p>
<pre class="literal-block">
$ python setup.py develop
</pre>
</div>
<div class="section" id="async-workers">
<h2><a class="toc-backref" href="#contents">Async Workers</a></h2>
<p>You may also want to install <a class="reference external" href="http://eventlet.net">Eventlet</a> or <a class="reference external" href="http://gevent.org">Gevent</a> if you expect that your
application code may need to pause for extended periods of time during request
processing. Check out the <a class="reference external" href="design.html">design docs</a> for more information on when you'll
want to consider one of the alternate worker types.</p>
<pre class="literal-block">
$ easy_install -U greenlet # Required for both
$ easy_install -U eventlet # For eventlet workers
$ easy_install -U gevent # For gevent workers
</pre>
<div class="note">
<p class="first admonition-title">Note</p>
<p>If installing <tt class="docutils literal">greenlet</tt> fails you probably need to install
the Python headers. These headers are available in most package
managers. On Ubuntu the package name for <tt class="docutils literal"><span class="pre">apt-get</span></tt> is
<tt class="docutils literal"><span class="pre">python-dev</span></tt>.</p>
<p class="last"><a class="reference external" href="http://gevent.org">Gevent</a> also requires that <tt class="docutils literal">libevent</tt> 1.4.x or 2.0.4 is installed.
This could be a more recent version than what is available in your
package manager. If <a class="reference external" href="http://gevent.org">Gevent</a> fails to build even with <tt class="docutils literal">libevent</tt>
installed, this is the most likely reason.</p>
</div>
</div>
<div class="section" id="ubuntu-debian">
<h2><a class="toc-backref" href="#contents">Ubuntu/Debian</a></h2>
<p>If you use <a class="reference external" href="http://www.ubuntu.com/">Ubuntu</a> karmic, you can update your system with packages from
our <a class="reference external" href="https://launchpad.net/~bchesneau/+archive/gunicorn">PPA</a> by adding <tt class="docutils literal">ppa:bchesneau/gunicorn</tt> to your system's Software
Sources.</p>
<p>Or this PPA can be added to your system manually by copying the lines below
and adding them to your system's software sources:</p>
<pre class="literal-block">
deb http://ppa.launchpad.net/bchesneau/gunicorn/ubuntu karmic main
deb-src http://ppa.launchpad.net/bchesneau/gunicorn/ubuntu karmic main
</pre>
<div class="section" id="signing-key">
<h3><a class="toc-backref" href="#contents">Signing key</a></h3>
<pre class="literal-block">
1024R/15E5EB06
</pre>
</div>
<div class="section" id="fingerprint">
<h3><a class="toc-backref" href="#contents">Fingerprint</a></h3>
<pre class="literal-block">
49AEEDFF5CDCD82CEA8AB4DABC981A8115E5EB06
</pre>
</div>
</div>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</body>
</html>

View File

@ -4,53 +4,28 @@
<meta charset="utf-8" />
<title>Green Unicorn - Installing Gunicorn</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<!--[if IE]>
<script>
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('nav');
document.createElement('time');
</script>
<![endif]-->
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div id="links">
Get the source via
<a href="http://github.com/benoitc/gunicorn">git</a>, then
<a href="http://github.com/benoitc/gunicorn/issues">send feedback</a>
</div>
</div>
<div id="menu">
<ul id="actions">
<li><a href="installation.html">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="deployment.html">Deployment</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="tuning.html">Tuning</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="installation">
<div class="container">
<div id="header">
<a href="http://gunicorn.org">
<img src="/images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="installation">
<h1 class="title">Installation</h1>
<div class="section" id="requirements">
<h1>Requirements</h1>
<h2>Requirements</h2>
<ul class="simple">
<li><strong>Python 2.x &gt;= 2.5</strong> (Python 3.x will be supported soon)</li>
<li>setuptools &gt;= 0.6c6</li>
@ -71,12 +46,12 @@ $ sudo easy_install -U gunicorn
</pre>
</div>
<div class="section" id="installing-from-source">
<h1>Installing from source</h1>
<h2>Installing from source</h2>
<p>You can install Gunicorn from source just as you would install any other
Python package. Gunicorn uses setuptools which will automatically fetch all
dependencies (including setuptools itself).</p>
<div class="section" id="get-a-copy">
<h2>Get a Copy</h2>
<h3>Get a Copy</h3>
<p>You can download a tarball of the latest sources from <a class="reference external" href="http://github.com/benoitc/gunicorn/downloads">GitHub Downloads</a> or
fetch them with <a class="reference external" href="http://git-scm.com/">git</a>:</p>
<pre class="literal-block">
@ -84,7 +59,7 @@ $ git clone git://github.com/benoitc/gunicorn.git
</pre>
</div>
<div class="section" id="id1">
<h2>Installation</h2>
<h3>Installation</h3>
<pre class="literal-block">
$ python setup.py install
</pre>
@ -98,7 +73,7 @@ $ python setup.py develop
</div>
</div>
<div class="section" id="enabling-async-workers">
<h1>Enabling async workers</h1>
<h2>Enabling async workers</h2>
<p>You may also want to install <a class="reference external" href="http://eventlet.net">Eventlet</a> or <a class="reference external" href="http://gevent.org">Gevent</a> if you expect that your
application code may need to pause for extended periods of time during
request processing. Check out the <a class="reference external" href="faq.html">FAQ</a> for more information on when you'll
@ -122,7 +97,7 @@ installed, this is the most likely reason.</p>
</div>
</div>
<div class="section" id="installing-on-ubuntu-debian-systems">
<h1>Installing on Ubuntu/Debian systems</h1>
<h2>Installing on Ubuntu/Debian systems</h2>
<p>If you use <a class="reference external" href="http://www.ubuntu.com/">Ubuntu</a> karmic, you can update your system with packages from
our <a class="reference external" href="https://launchpad.net/~bchesneau/+archive/gunicorn">PPA</a> by adding <tt class="docutils literal">ppa:bchesneau/gunicorn</tt> to your system's Software
Sources.</p>
@ -143,12 +118,10 @@ deb-src http://ppa.launchpad.net/bchesneau/gunicorn/ubuntu karmic main
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</div>
</body>
</html>
</html>

View File

@ -4,53 +4,31 @@
<meta charset="utf-8" />
<title>Green Unicorn - News</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<!--[if IE]>
<script>
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('nav');
document.createElement('time');
</script>
<![endif]-->
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div id="links">
Get the source via
<a href="http://github.com/benoitc/gunicorn">git</a>, then
<a href="http://github.com/benoitc/gunicorn/issues">send feedback</a>
</div>
</div>
<div id="menu">
<ul id="actions">
<li><a href="installation.html">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="deployment.html">Deployment</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="tuning.html">Tuning</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="news">
<h1 class="title">News</h1>
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
<div class="document">
<div class="section" id="dev-2010-05-17">
<h1>0.9.0-dev / 2010-05-17</h1>
<h2>0.9.0-dev / 2010-05-17</h2>
<ul class="simple">
<li>Fix pidfile</li>
<li>Fix QUIT/HUP in async workers</li>
@ -89,8 +67,8 @@ are forked.</li>
<li>Delay application loading until after processing all configuration</li>
</ul>
</div>
<div class="section" id="id4">
<h1>0.8.0 / 2010-04-22</h1>
<div class="section" id="id2">
<h2>0.8.0 / 2010-04-22</h2>
<ul class="simple">
<li>Refactored Worker management for better async support. Now use the -k option
to set the type of request processing to use</li>
@ -105,8 +83,8 @@ to set the type of request processing to use</li>
<li>Fix a bug in start_response on error</li>
</ul>
</div>
<div class="section" id="id6">
<h1>0.7.1 / 2010-04-01</h1>
<div class="section" id="id4">
<h2>0.7.1 / 2010-04-01</h2>
<ul class="simple">
<li>Fix bug when responses have no body.</li>
</ul>
@ -128,22 +106,22 @@ to set the type of request processing to use</li>
<li>Fix Exception Error</li>
</ul>
</div>
<div class="section" id="id9">
<h1>0.6.4 / 2010-03-08</h1>
<div class="section" id="id7">
<h2>0.6.4 / 2010-03-08</h2>
<ul class="simple">
<li>Use cStringIO for performance when possible.</li>
<li>Fix worker freeze when a remote connection closes unexpectedly.</li>
</ul>
</div>
<div class="section" id="id10">
<h1>0.6.3 / 2010-03-07</h1>
<div class="section" id="id8">
<h2>0.6.3 / 2010-03-07</h2>
<ul class="simple">
<li>Make HTTP parsing faster.</li>
<li>Various bug fixes</li>
</ul>
</div>
<div class="section" id="id11">
<h1>0.6.2 / 2010-03-01</h1>
<div class="section" id="id9">
<h2>0.6.2 / 2010-03-01</h2>
<ul class="simple">
<li>Added support for chunked response.</li>
<li>Added proc_name option to the config file.</li>
@ -153,31 +131,31 @@ temporary data.</li>
<li>Workers are now murdered by age (the oldest is killed first).</li>
</ul>
</div>
<div class="section" id="id12">
<h1>0.6.1 / 2010-02-24</h1>
<div class="section" id="id10">
<h2>0.6.1 / 2010-02-24</h2>
<ul class="simple">
<li>Added gunicorn config file support for Django admin command</li>
<li>Fix gunicorn config file. -c was broken.</li>
<li>Removed TTIN/TTOU from workers which blocked other signals.</li>
</ul>
</div>
<div class="section" id="id13">
<h1>0.6 / 2010-02-22</h1>
<div class="section" id="id11">
<h2>0.6 / 2010-02-22</h2>
<ul class="simple">
<li>Added setproctitle support</li>
<li>Change privilege switch behavior. We now work like NGINX, master keeps the
permissions, new uid/gid permissions are only set for workers.</li>
</ul>
</div>
<div class="section" id="id14">
<h1>0.5.1 / 2010-02-22</h1>
<div class="section" id="id12">
<h2>0.5.1 / 2010-02-22</h2>
<ul class="simple">
<li>Fix umask</li>
<li>Added Debian packaging</li>
</ul>
</div>
<div class="section" id="id15">
<h1>0.5 / 2010-02-20</h1>
<div class="section" id="id13">
<h2>0.5 / 2010-02-20</h2>
<ul class="simple">
<li>Added <a class="reference external" href="configuration.html">configuration file</a> handler.</li>
<li>Added support for pre/post fork hooks</li>
@ -194,12 +172,11 @@ permissions, new uid/gid permissions are only set for workers.</li>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</div>
</body>
</html>
</html>

165
doc/htdocs/run.html Normal file
View File

@ -0,0 +1,165 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Green Unicorn - Run</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
<div class="document">
<div class="contents sidebar topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#commands" id="id1">Commands</a><ul>
<li><a class="reference internal" href="#gunicorn" id="id2">gunicorn</a></li>
<li><a class="reference internal" href="#gunicorn-django" id="id3">gunicorn_django</a></li>
<li><a class="reference internal" href="#gunicorn-paster" id="id4">gunicorn_paster</a></li>
</ul>
</li>
<li><a class="reference internal" href="#integration" id="id5">Integration</a><ul>
<li><a class="reference internal" href="#django-manage-py" id="id6">Django ./manage.py</a></li>
<li><a class="reference internal" href="#paster-serve" id="id7">paster serve</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="commands">
<h2><a class="toc-backref" href="#contents">Commands</a></h2>
<p>After installing Gunicorn you will have access to three command line scripts
that can be used for serving the various supported web frameworks:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal">gunicorn</tt></li>
<li><tt class="docutils literal">gunicorn_django</tt></li>
<li><tt class="docutils literal">gunicorn_paster</tt></li>
</ul>
</blockquote>
<div class="section" id="gunicorn">
<h3><a class="toc-backref" href="#contents">gunicorn</a></h3>
<p>The first and most basic script is used to serve 'bare' WSGI applications
that don't require a translation layer. Basic usage:</p>
<pre class="literal-block">
$ gunicorn [OPTIONS] APP_MODULE
</pre>
<p>Where <tt class="docutils literal">APP_MODULE</tt> is of the pattern <tt class="docutils literal"><span class="pre">$(MODULE_NAME):$(VARIABLE_NAME)</span></tt>. The
module name can be a full dotted path. The variable name refers to a WSGI
callable that should be found in the specified module.</p>
<p>Example with test app:</p>
<pre class="literal-block">
$ cd examples
$ cat test.py
# -*- coding: utf-8 -
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
def app(environ, start_response):
&quot;&quot;&quot;Simplest possible application object&quot;&quot;&quot;
data = 'Hello, World!\n'
status = '200 OK'
response_headers = [
('Content-type','text/plain'),
('Content-Length', str(len(data)))
]
start_response(status, response_headers)
return iter([data])
$ gunicorn --workers=2 test:app
</pre>
</div>
<div class="section" id="gunicorn-django">
<h3><a class="toc-backref" href="#contents">gunicorn_django</a></h3>
<p>You might not have guessed it, but this script is used to serve Django
applications. Basic usage:</p>
<pre class="literal-block">
$ gunicorn_django [OPTIONS] [SETTINGS_PATH]
</pre>
<p>By default <tt class="docutils literal">SETTINGS_PATH</tt> will look for <tt class="docutils literal">settings.py</tt> in the current
directory.</p>
<p>Example with your Django project:</p>
<pre class="literal-block">
$ cd path/to/yourdjangoproject
$ gunicorn_django --workers=2
</pre>
</div>
<div class="section" id="gunicorn-paster">
<h3><a class="toc-backref" href="#contents">gunicorn_paster</a></h3>
<p>Yeah, for Paster-compatible frameworks (Pylons, TurboGears 2, ...). We
apologize for the lack of script name creativity. And some usage:</p>
<pre class="literal-block">
$ gunicorn_paster [OPTIONS] paste_config.ini
</pre>
<p>Simple example:</p>
<pre class="literal-block">
$ cd yourpasteproject
$ gunicorn_paste --workers=2 development.ini
</pre>
</div>
</div>
<div class="section" id="integration">
<h2><a class="toc-backref" href="#contents">Integration</a></h2>
<p>Alternatively, we also provide integration for both Django and Paster
applications in case your deployment strategy would be better served by such
invocation styles.</p>
<div class="section" id="django-manage-py">
<h3><a class="toc-backref" href="#contents">Django ./manage.py</a></h3>
<p>You can add a <tt class="docutils literal">run_gunicorn</tt> command to your <tt class="docutils literal">./manage.py</tt> simply by adding
gunicorn to your <tt class="docutils literal">INSTALLED_APPS</tt>:</p>
<pre class="literal-block">
INSTALLED_APPS = (
...
&quot;gunicorn&quot;,
)
</pre>
<p>Then you can run:</p>
<pre class="literal-block">
python manage.py run_gunicorn
</pre>
</div>
<div class="section" id="paster-serve">
<h3><a class="toc-backref" href="#contents">paster serve</a></h3>
<p>If you're wanting to keep on keeping on with the usual paster serve command,
you can specify the Gunicorn server settings in your configuration file:</p>
<pre class="literal-block">
[server:main]
use = egg:gunicorn#main
host = 127.0.0.1
port = 5000
</pre>
<p>And then as per usual:</p>
<pre class="literal-block">
$ cd yourpasteproject
$ paster serve development.ini workers=2
</pre>
</div>
</div>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</body>
</html>

View File

@ -4,53 +4,32 @@
<meta charset="utf-8" />
<title>Green Unicorn - Tuning</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<!--[if IE]>
<script>
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('nav');
document.createElement('time');
</script>
<![endif]-->
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div id="links">
Get the source via
<a href="http://github.com/benoitc/gunicorn">git</a>, then
<a href="http://github.com/benoitc/gunicorn/issues">send feedback</a>
</div>
</div>
<div id="menu">
<ul id="actions">
<li><a href="installation.html">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="deployment.html">Deployment</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="tuning.html">Tuning</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="tuning">
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
<div class="document" id="tuning">
<h1 class="title">Tuning</h1>
<div class="section" id="unicorn-configuration">
<h1>Unicorn Configuration</h1>
<h2>Unicorn Configuration</h2>
<p>DO NOT scale the number of workers to the number of clients you expect to have.
Gunicorn should only need 4-12 worker processes to handle hundreds or thousands
of simultaneous clients. Remember, Gunicorn is <strong>NOT</strong> designed for serving slow
@ -58,7 +37,7 @@ clients, that's the job of <a class="reference external" href="http://www.nginx.
<p>See <a class="reference external" href="configuration.html">Configuration</a> for a more thorough description of the available parameters.</p>
</div>
<div class="section" id="kernel-parameters">
<h1>Kernel Parameters</h1>
<h2>Kernel Parameters</h2>
<p>When dealing with large numbers of concurrent connections there are a handful of
kernel parameters that you might need to adjust. Generally these should only
affect sites with a very large concurrent load. These parameters are not
@ -68,7 +47,7 @@ running.</p>
slightly different flags. Always reference the appropriate man pages if
uncertain.</p>
<div class="section" id="file-descriptor-limits">
<h2>File Descriptor Limits</h2>
<h3>File Descriptor Limits</h3>
<p>One of the first settings that usually needs to be bumped is the maximum number
of open file descriptors for a given process. For the confused out there,
remember that Unices treat sockets as files.</p>
@ -77,7 +56,7 @@ $ sudo ulimit -n 2048
</pre>
</div>
<div class="section" id="listen-queue-size">
<h2>Listen Queue Size</h2>
<h3>Listen Queue Size</h3>
<p>Listening sockets have an associated queue of incoming connections that are
waiting to be accepted. If you happen to have a stampede of clients that fill up
this queue new connections will eventually start getting dropped.</p>
@ -86,7 +65,7 @@ $ sudo sysctl -w kern.ipc.somaxconn=&quot;2048&quot;
</pre>
</div>
<div class="section" id="ephemeral-port-range">
<h2>Ephemeral Port Range</h2>
<h3>Ephemeral Port Range</h3>
<p>After a socket is closed it enters the TIME_WAIT state. This can become an issue
after a prolonged burst of client activity. Eventually the ephemeral port range
is exhausted which can cause new connections to stall while they wait for a
@ -100,12 +79,11 @@ $ sudo sysctl -w net.inet.ip.portrange.first=&quot;8048&quot;
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</div>
</body>
</html>

View File

@ -4,74 +4,52 @@
<meta charset="utf-8" />
<title>Green Unicorn - Command Line Usage</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<!--[if IE]>
<script>
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('nav');
document.createElement('time');
</script>
<![endif]-->
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div id="links">
Get the source via
<a href="http://github.com/benoitc/gunicorn">git</a>, then
<a href="http://github.com/benoitc/gunicorn/issues">send feedback</a>
</div>
</div>
<div id="menu">
<ul id="actions">
<li><a href="installation.html">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="deployment.html">Deployment</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="tuning.html">Tuning</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="usage">
<div class="container">
<div id="header">
<a href="http://gunicorn.org">
<img src="/images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>
<div class="document" id="usage">
<h1 class="title">Usage</h1>
<p>After installing Gunicorn you will have access to three command line scripts
that can be used for serving the various supported web frameworks: <tt class="docutils literal">gunicorn</tt>,
<tt class="docutils literal">gunicorn_django</tt>, and <tt class="docutils literal">gunicorn_paster</tt>.</p>
<div class="section" id="commonly-used-arguments">
<h1>Commonly Used Arguments</h1>
<h2>Commonly Used Arguments</h2>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-c</span> CONFIG, <span class="pre">--config=CONFIG</span></tt> - Specify the path to a <a class="reference external" href="configuration.html">config file</a></li>
<li><tt class="docutils literal"><span class="pre">-b</span> BIND, <span class="pre">--bind=BIND</span></tt> - Specify a server socket to bind. Server sockets
can be any of <tt class="docutils literal">$(HOST)</tt>, <tt class="docutils literal"><span class="pre">$(HOST):$(PORT)</span></tt>, or <tt class="docutils literal"><span class="pre">unix:$(PATH)</span></tt>.
An IP is a valid <tt class="docutils literal">$(HOST)</tt>.</li>
<li><tt class="docutils literal"><span class="pre">-w</span> WORKERS, <span class="pre">--workers=WORKERS</span></tt> - The number of worker processes. This
number should generally be between 2-4 workers per core in the server.
Check the <a class="reference external" href="faq.html">FAQ</a> for ideas on tuning this parameter.</li>
<li><tt class="docutils literal"><span class="pre">-k</span> WORKERCLASS, <span class="pre">--worker-class=WORKERCLASS</span></tt> - The type of worker process
to run. You'll definitely want to read the <a class="reference external" href="deployment.html">production page</a> for the
implications of this parameter. You can set this to <tt class="docutils literal"><span class="pre">egg:gunicorn#$(NAME)</span></tt>
where <tt class="docutils literal">$(NAME)</tt> is one of <tt class="docutils literal">sync</tt>, <tt class="docutils literal">eventlet</tt>, <tt class="docutils literal">gevent</tt>, or
<tt class="docutils literal">tornado</tt>. <tt class="docutils literal">sync</tt> is the default.</li>
<li><tt class="docutils literal"><span class="pre">-n</span> APP_NAME, <span class="pre">--name=APP_NAME</span></tt> - If <a class="reference external" href="http://pypi.python.org/pypi/setproctitle/">setproctitle</a> is installed you can
adjust the name of Gunicorn process as they appear in the process system
table (which affects tools like <tt class="docutils literal">ps</tt> and <tt class="docutils literal">top</tt>).</li>
</ul>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">-c</span> CONFIG, <span class="pre">--config=CONFIG</span></tt></dt>
<dd>Specify the path to a <a class="reference external" href="configuration.html">config file</a></dd>
<dt><tt class="docutils literal"><span class="pre">-b</span> BIND, <span class="pre">--bind=BIND</span></tt></dt>
<dd>Specify a server socket to bind. Server sockets can be any of <tt class="docutils literal">$(HOST)</tt>,
<tt class="docutils literal"><span class="pre">$(HOST):$(PORT)</span></tt>, or <tt class="docutils literal"><span class="pre">unix:$(PATH)</span></tt>. An IP is a valid <tt class="docutils literal">$(HOST)</tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">-w</span> WORKERS, <span class="pre">--workers=WORKERS</span></tt></dt>
<dd>The number of worker processes. This number should generally be between 2-4
workers per core in the server. Check the <a class="reference external" href="faq.html">FAQ</a> for ideas on tuning this
parameter.</dd>
<dt><tt class="docutils literal"><span class="pre">-k</span> WORKERCLASS, <span class="pre">--worker-class=WORKERCLASS</span></tt></dt>
<dd>The type of worker process to run. You'll definitely want to read the
<a class="reference external" href="deployment.html">production page</a> for the implications of this parameter. You can set this
to <tt class="docutils literal"><span class="pre">egg:gunicorn#$(NAME)</span></tt> where <tt class="docutils literal">$(NAME)</tt> is one of <tt class="docutils literal">sync</tt>,
<tt class="docutils literal">eventlet</tt>, <tt class="docutils literal">gevent</tt>, or <tt class="docutils literal">tornado</tt>. <tt class="docutils literal">sync</tt> is the default.</dd>
<dt><tt class="docutils literal"><span class="pre">-n</span> APP_NAME, <span class="pre">--name=APP_NAME</span></tt></dt>
<dd>If <a class="reference external" href="http://pypi.python.org/pypi/setproctitle/">setproctitle</a> is installed you can adjust the name of Gunicorn process as
they appear in the process system table (which affects tools like <tt class="docutils literal">ps</tt> and
<tt class="docutils literal">top</tt>).</dd>
</dl>
</blockquote>
<p>There are various other parameters that affect user privileges, logging, etc.
You can see the complete list at the bottom of this page or as expected with:</p>
@ -80,7 +58,7 @@ $ gunicorn -h
</pre>
</div>
<div class="section" id="gunicorn">
<h1>gunicorn</h1>
<h2>gunicorn</h2>
<p>The first and most basic script is used to server 'bare' WSGI applications
that don't require a translation layer. Basic usage:</p>
<pre class="literal-block">
@ -96,7 +74,7 @@ $ gunicorn --workers=2 test:app
</pre>
</div>
<div class="section" id="gunicorn-django">
<h1>gunicorn_django</h1>
<h2>gunicorn_django</h2>
<p>You might not have guessed it, but this script is used to server Django
applications. Basic usage:</p>
<pre class="literal-block">
@ -125,7 +103,7 @@ python manage.py run_gunicorn
</pre>
</div>
<div class="section" id="gunicorn-paster">
<h1>gunicorn_paster</h1>
<h2>gunicorn_paster</h2>
<p>Yeah, for Paster-compatible frameworks (Pylons, TurboGears 2, ...). We
apologize for the lack of script name creativity. And some usage:</p>
<pre class="literal-block">
@ -151,7 +129,7 @@ $ paster serve development.ini workers=2
</pre>
</div>
<div class="section" id="full-command-line-usage">
<h1>Full Command Line Usage</h1>
<h2>Full Command Line Usage</h2>
<pre class="literal-block">
$ gunicorn -h
Usage: gunicorn [OPTIONS] APP_MODULE
@ -185,12 +163,12 @@ Options:
</pre>
</div>
<div class="section" id="framework-examples">
<h1>Framework Examples</h1>
<h2>Framework Examples</h2>
<p>This is an incomplete list of examples of using Gunicorn with various
Python web frameworks. If you have an example to add you're very much
invited to submit a ticket to the <a class="reference external" href="http://github.com/benoitc/gunicorn/issues">issue tracker</a> to have it included.</p>
<div class="section" id="itty">
<h2>Itty</h2>
<h3>Itty</h3>
<p>Itty comes with builtin Gunicorn support. The Itty &quot;Hello, world!&quot; looks
like such:</p>
<pre class="literal-block">
@ -204,7 +182,7 @@ run_itty(server='gunicorn')
</pre>
</div>
<div class="section" id="flask">
<h2>Flask</h2>
<h3>Flask</h3>
<p>Flask applications are WSGI compatible. Given this Flask app in an importable
Python module &quot;helloflask.py&quot;:</p>
<pre class="literal-block">
@ -225,12 +203,10 @@ can be as simple as &quot;exists in the current directory&quot;.</p>
</div>
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,132 +0,0 @@
template: doc.html
title: The Configuration File
The Configuration File
======================
Gunicorn 0.5 introduced the ability to use a Python configuration file. Gunicorn
will look for ``gunicorn.conf.py`` in the current working directory or what ever
path is specified on the command line with the ``-c`` option.
Example gunicorn.conf.py
------------------------
::
backlog = 2048 # The listen queue size for the server socket
bind = "127.0.0.1:8000" # Or "unix:/tmp/gunicorn.sock"
daemon = False # Whether work in the background
debug = False # Some extra logging
keepalive = 2 # Time we wait for next connection (in seconds)
logfile = "-" # Name of the log file
loglevel = "info" # 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
spew=False # Display trace
timeout=30 # Worker timeout
tmp_upload_dir = None # Set path used to store temporary uploads
worker_class = "egg:gunicorn#sync" # The type of request processing to use
worker_connections=1000 # Maximum number of simultaneous connections
after_fork=lambda server, worker: server.log.info(
"Worker spawned (pid: %s)" % worker.pid)
before_fork=lambda server, worker: True
before_exec=lambda server: server.log.info("Forked child, reexecuting")
when_ready=lambda server: server.log.info("Gunicorn started.")
Parameter Descriptions
----------------------
after_fork(server, worker):
This is called by the worker after initialization.
worker_class:
Define the type of worker to use. A worker process all the requests send by
the arbiter.By default the worker_class is `egg:gunicorn#sync`. This worker
only supports fast request handling requiring a buffering HTTP proxy.
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 worker. Gunicorn has three async workers built in
using `Tornado`_, `Eventlet`_ or `Gevent`_. You can also use the Evenlet
worker with the `Twisted`_ helper.
backlog:
The backlog parameter defines the maximum length for the queue of pending
connections. The default is 2048. See listen(2) for more information
before_fork(server, worker):
This is called by the worker just before forking.
before_exec(server):
This function is called before relaunching the master. This happens when
the master receives a HUP or USR2 signal.
bind:
The address on which workers are listening. It can be a TCP address with a
format of ``IP:PORT`` or a Unix socket address like
``unix:/path/to/socketfile``.
daemon:
Whether or not to detach the server from the controlling terminal.
debug:
If ``True``, only one worker will be launch and the variable
``wsgi.multiprocess`` will be set to False.
group:
The group in which worker processes will be launched.
keepalive:
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.
logfile:
The path to the log file ``-`` (stdout) by default.
loglevel:
The level at which to log. ``info``, ``debug``, or ``error`` for instance.
Only log messages of equal or greater severity are logged.
pidfile:
A file to store the master's PID.
proc_name:
A name for the master process. Only takes effect if setproctitle_ is
installed. This alters the process names listed by commands like ``ps``.
umask:
Used to set the umask when daemonizing.
user:
The user as which worker processes will by launched.
when_ready(server):
This is called by the arbiter just after Gunicorn started.
worker_connections:
Number of simultaneous connections a worker can handle when used with
Eventlet or Gevent arbiter. The default is 1000.
timeout:
Set worker timeout.
tmp_upload_dir:
Set the path used to store temporarily the body of the request.
.. _helper: http://bitbucket.org/which_linden/eventlet/src/tip/README.twisted
.. _Eventlet: http://eventlet.net
.. _Gevent: http://gevent.org
.. _Twisted: http://twistedmatrix.com
.. _Tornado: http://www.tornadoweb.org/
.. _setproctitle: http://pypi.python.org/pypi/setproctitle

101
doc/site/configure.rst Normal file
View File

@ -0,0 +1,101 @@
template: doc.html
title: Configure
insert_settings: true
.. contents::
:class: sidebar
:backlinks: top
Overview
--------
Gunicorn pulls configuration information from three distinct places.
The first place that Gunicorn will read configuration from is the framework
specific configuration file. Currently this only affects Paster applications.
The second source of configuration information is a configuration file that is
optionally specified on the command line. Anything specified in the Gunicorn
config file will override any framework specific settings.
Lastly, the command line arguments used to invoke Gunicorn are the final place
considered for configuration settings. If an option is specified on the command
line, this is the value that will be used.
Once again, in order of least to most authoritative:
1. Framework Settings
2. Configuration File
3. Command Line
Framework Settings
------------------
Currently, only Paster applications have access to framework specific
settings. If you have ideas for providing settings to WSGI applications or
pulling information from Django's settings.py feel free to open an issue_ to
let us know.
.. _issue: http://github.com/benoitc/gunicorn/issues
Paster Applications
+++++++++++++++++++
In your INI file, you can specify to use Gunicorn as the server like such::
[server:main]
use = egg:gunicorn#main
host = 192.168.0.1
port = 80
workers = 2
proc_name = brim
Any parameters that Gunicorn knows about will automatically be inserted into
the base configuration. Remember that these will be overridden by the config
file and/or the command line.
Configuration File
------------------
The configuration file should be a valid Python source file. It only needs to
be readable from the file system. More specifically, it does not need to be
importable. Any Python is valid. Just consider that this will be run every time
you start Gunicorn (including when you signal Gunicorn to reload).
To set a parameter, just assign to it. There's no special syntax. The values
you provide will be used for the configuration values.
For instance::
import os
def numCPUs():
if not hasattr(os, "sysconf"):
raise RuntimeError("No sysconf detected.")
return os.sysconf("SC_NPROCESSORS_ONLN")
bind = "127.0.0.1:8000"
workers = numCPUs() * 2 + 1
Command Line
------------
If an option is specified on the command line, it overrides all other values
that may have been specified in the app specific settings, or in the optional
configuration file. Not all Gunicorn settings are available to be set from the
command line. To see the full list of command line settings you can do the
usual::
$ gunicorn -h
There is also a ``--version`` flag available to the command line scripts that
isn't mentioned in the list of settings.
Settings
--------
This is an exhaustive list of settings for Gunicorn. Some settings are only
able to be set from a configuration file. The setting name is what should be
used in the configuration file. The command line arguments are listed as well
for reference on setting at the command line.
%(settings)s

View File

@ -1,38 +1,17 @@
template: doc.html
title: Deployment
title: Deploy
Production Setup
================
.. contents::
:class: sidebar
:backlinks: top
Synchronous vs Asynchronous workers
-----------------------------------
The default configuration of Gunicorn assumes that your application code is
mostly CPU bound. The default worker class is a simple single threaded loop that
just processes requests as they are received. In general, most applications will
do just fine with this sort of configuration.
This CPU bound assumption is why the default configuration needs to use a
buffering HTTP proxy like Nginx_ to protect the Gunicorn server. If we allowed
direct connections a client could send a request slowly thus starving the server
of free worker processes (because they're all stuck waiting for data).
Example use-cases for asynchronous workers:
* Applications making long blocking calls (Ie, to external web services)
* Serving requests directly to the internet
* Streaming requests and responses
* Long polling
* Web sockets
* Comet
Basic Nginx Configuration
-------------------------
Nginx Configuration
-------------------
Although there are many HTTP proxies available, we strongly advise that you
use Nginx_. If you choose another proxy server you need to make sure that it
buffers slow clients when you use default Gunicorn workers. Without this
buffering Gunicorn will be easily susceptible to Denial-Of-Service attacks.
buffering Gunicorn will be easily susceptible to denial-of-service attacks.
You can use slowloris_ to check if your proxy is behaving properly.
An `example configuration`_ file for fast clients with Nginx_::
@ -110,8 +89,8 @@ To turn off buffering, you only need to add ``proxy_buffering off;`` to your
}
...
Working with Virtualenv
-----------------------
Using Virtualenv
----------------
To serve an app from a Virtualenv_ it is generally easiest to just install
Gunicorn directly into the Virtualenv. This will create a set of Gunicorn
@ -129,8 +108,8 @@ this::
Then you just need to use one of the three Gunicorn scripts that was installed
into ``~/venvs/webapp/bin``.
Daemon Monitoring
-----------------
Monitoring
----------
.. note::
Make sure that when using either of these service monitors you do not
@ -140,6 +119,9 @@ Daemon Monitoring
confuses the monitor services.
Runit
+++++
A popular method for deploying Gunicorn is to have it monitored by runit_.
An `example service`_ definition::
@ -156,6 +138,9 @@ An `example service`_ definition::
cd $ROOT
exec $GUNICORN -C $ROOT/gunicorn.conf.py --pidfile=$PID $APP
Supervisor
++++++++++
Another useful tool to monitor and control Gunicorn is Supervisor_. A
`simple configuration`_ is::

94
doc/site/design.rst Normal file
View File

@ -0,0 +1,94 @@
template: doc.html
title: Design
.. contents::
:class: sidebar
:backlinks: top
Server Model
============
Gunicorn is based on the pre-fork worker model. This means that there is a
central master process that manages a set of worker processes. The master
never knows anything about individual clients. All requests and responses are
handled completely by worker processes.
Master
------
The master process is a simple loop that listens for various process signals
and reacts accordingly. It manages the list of running workers by listening
for signals like TTIN, TTOU, and CHLD. TTIN and TTOU tell the master to
increase or decrease the number of running workers. CHLD indicates that a child
process has terminated, in this case the master process automatically restarts
the failed worker.
Sync Workers
------------
The most basic and the default worker type is a synchronous worker class that
handles a single request at a time. This model is the simplest to reason about
as any errors will affect at most a single request. Though as we describe below
only processing a single request at a time requires some assumptions about how
applications are programmed.
Async Workers
-------------
The asynchronous workers available are based on Greenlets_ (via Eventlet_ and
Gevent_). Greenlets are an implementation of cooperative multi-threading for
Python. In general, an application should be able to make use of these worker
classes with no changes.
Tornado Workers
---------------
There's also a Tornado worker class. It can be used to write applications using
the Tornado framework. Although the Tornado workers are capable of serving a
WSGI application, this is not a recommended configuration.
Choosing a Worker Type
======================
The default synchronous workers assume that your application is resource bound
in terms of CPU and network bandwidth. Generally this means that your
application shouldn't do anything that takes an undefined amount of time. For
instance, a request to the internet meets this criteria. At some point the
external network will fail in such a way that clients will pile up on your
servers.
This resource bound assumption is why we require a buffering proxy in front of a
default configuration Gunicorn. If you exposed synchronous workers to the
internet, a DOS attack would be trivial by creating a load that trickles data to
the servers. For the curious, Slowloris_ is an example of this type of load.
Some examples of behavior requiring asynchronous workers:
* Applications making long blocking calls (Ie, external web services)
* Serving requests directly to the internet
* Streaming requests and responses
* Long polling
* Web sockets
* Comet
How Many Workers?
=================
Gunicorn relies on the operating system to provide all of the load balancing
when handling requests. Generally we recommend ``(2 x $num_cores) + 1`` as the
number of workers to start off with. While not overly scientific, the formula
is based on the assumption that for a given core, one worker will be reading
or writing from the socket while the other worker is processing a request.
Obviously, your particular hardware and application are going to affect what
the optimal number of workers is. Our recommendation is to start with the above
guess and tune using TTIN and TTOU signals while the application is under load.
Always remember, there is such a thing as too many workers. After a point your
worker processes will start thrashing system resources decreasing the throughput
of the entire system.
.. _Greenlets: http://bitbucket.org/ambroff/greenlet
.. _Eventlet: http://eventlet.net
.. _Gevent: http://gevent.org
.. _Slowloris: http://ha.ckers.org/slowloris/

View File

@ -1,33 +1,71 @@
template: doc.html
title: FAQ
FAQ
===
.. contents:: Questions
:backlinks: top
How do I know which type of worker to use?
Test. Read the "Synchronous vs Asynchronous workers" section on the
deployment_ page. Test some more.
What types of workers are there?
These can all be used with the ``-k`` option and specifying them
as ``egg:gunicorn#$(NAME)`` where ``$(NAME)`` is chosen from this list.
* ``sync`` - The default synchronous worker
* ``eventlet`` - Asynchronous workers based on Greenlets
* ``gevent`` - Asynchronous workers based on Greenlets
* ``tornado`` - Asynchronous workers based on FriendFeed's Tornado server.
WSGI Bits
=========
How might I test a proxy configuration?
Check out slowloris_ for a script that will generate significant slow
traffic. If your application remains responsive through out that test you
should be comfortable that all is well with your configuration.
How do I set SCRIPT_NAME?
-------------------------
By default ``SCRIPT_NAME`` is an empy string. The value could be set by
setting ``SCRIPT_NAME`` in the environment or as an HTTP header.
Server Stuff
============
How do I reload my application in Gunicorn?
You can gracefully reload by sending HUP signal to gunicorn::
-------------------------------------------
You can gracefully reload by sending HUP signal to gunicorn::
$ kill -HUP masterpid
How do I increase or decrease the number of running workers dynamically?
How might I test a proxy configuration?
---------------------------------------
The Slowloris_ script is a great way to test that your proxy is correctly
buffering responses for the synchronous workers.
How can I name processes?
-------------------------
If you install the Python package setproctitle_ Gunicorn will set the process
names to something a bit more meaningful. This will affect the output you see
in tools like ``ps`` and ``top``. This helps for distinguishing the master
process as well as between masters when running more than one app on a single
machine. See the proc_name_ setting for more information.
.. _slowloris: http://ha.ckers.org/slowloris/
.. _setproctitle: http://pypi.python.org/pypi/setproctitle
.. _proc_name: /configure.html#proc-name
Worker Processes
================
How do I know which type of worker to use?
------------------------------------------
Read the design_ page for help on the various worker types.
What types of workers are there?
--------------------------------
Check out the configuration docs for worker_class_
How can I figure out the best number of worker processes?
---------------------------------------------------------
Here is our recommendation for tuning the `number of workers`_.
How can I change the number of workers dynamically?
---------------------------------------------------
To increase the worker count by one::
$ kill -TTIN $masterpid
@ -36,21 +74,7 @@ How do I increase or decrease the number of running workers dynamically?
$ kill -TTOU $masterpid
How can I figure out the best number of worker processes?
Start gunicorn with an approximate number of worker processes. Then use the
TTIN and/or TTOU signals to adjust the number of workers under load.
.. _design: /design.html
.. _worker_class: /configure.html#worker-class
.. _`number of workers`: /design.html#how-many-workers
How do I set SCRIPT_NAME?
By default ``SCRIPT_NAME`` is an empy string. The value could be set by
setting ``SCRIPT_NAME`` in the environment or as an HTTP header.
How can I name processes?
You need to install the Python package setproctitle_. Then you can specify
a base process name on the command line (``-n``) or in the configuration
file.
.. _deployment: http://gunicorn.org/deployment.html
.. _slowloris: http://ha.ckers.org/slowloris/
.. _setproctitle: http://pypi.python.org/pypi/setproctitle
.. _Eventlet: http://eventlet.net
.. _Gevent: http://gevent.org

View File

@ -2,7 +2,7 @@ template: index.html
title: Welcome
Green Unicorn
=============
-------------
Gunicorn 'Green Unicorn' is a WSGI_ HTTP Server for UNIX. It's a pre-fork
worker model ported from Ruby's Unicorn_ project. The Gunicorn server is

View File

@ -1,8 +1,9 @@
template: doc.html
title: Installing Gunicorn
title: Install
Installation
============
.. contents::
:class: sidebar
:backlinks: top
Requirements
------------
@ -11,8 +12,8 @@ Requirements
- setuptools >= 0.6c6
- nosetests (for the test suite only)
Installing with easy_install
----------------------------
With easy_install
-----------------
If you don't already have ``easy_install`` available you'll want to download
and run the ``ez_setup.py`` script::
@ -24,44 +25,44 @@ To install or upgrade to the latest released version of Gunicorn::
$ sudo easy_install -U gunicorn
Installing from source
----------------------
From Source
-----------
You can install Gunicorn from source just as you would install any other
Python package. Gunicorn uses setuptools which will automatically fetch all
dependencies (including setuptools itself).
Get a Copy
++++++++++
You can download a tarball of the latest sources from `GitHub Downloads`_ or
fetch them with git_::
# Using git:
$ git clone git://github.com/benoitc/gunicorn.git
$ cd gunicorn
Installation
++++++++++++
# Or using a tarball:
$ wget http://github.com/benoitc/gunicorn/tarball/master -o gunicorn.tar.gz
$ tar -xvzf gunicorn.tar.gz
$ cd gunicorn-$HASH/
::
$ python setup.py install
# Install
$ sudo python setup.py install
If you've cloned the git repository, its highly recommended that you use the
``develop`` command which will allow you to use Gunicorn from the source
directory. This will allow you to keep up to date with development on GitHub as
well as make changes to the source::
$ python setup.py develop
$ python setup.py develop
Enabling async workers
----------------------
Async Workers
-------------
You may also want to install Eventlet_ or Gevent_ if you expect that your
application code may need to pause for extended periods of time during
request processing. Check out the FAQ_ for more information on when you'll
application code may need to pause for extended periods of time during request
processing. Check out the `design docs`_ for more information on when you'll
want to consider one of the alternate worker types.
To install eventlet::
::
$ easy_install -U greenlet # Required for both
$ easy_install -U eventlet # For eventlet workers
@ -78,8 +79,8 @@ To install eventlet::
package manager. If Gevent_ fails to build even with ``libevent``
installed, this is the most likely reason.
Installing on Ubuntu/Debian systems
-----------------------------------
Ubuntu/Debian
-------------
If you use Ubuntu_ karmic, you can update your system with packages from
our PPA_ by adding ``ppa:bchesneau/gunicorn`` to your system's Software
@ -91,16 +92,22 @@ and adding them to your system's software sources::
deb http://ppa.launchpad.net/bchesneau/gunicorn/ubuntu karmic main
deb-src http://ppa.launchpad.net/bchesneau/gunicorn/ubuntu karmic main
Signing key::
Signing key
+++++++++++
::
1024R/15E5EB06
Fingerprint::
Fingerprint
+++++++++++
::
49AEEDFF5CDCD82CEA8AB4DABC981A8115E5EB06
.. _`GitHub Downloads`: http://github.com/benoitc/gunicorn/downloads
.. _FAQ: faq.html
.. _`design docs`: design.html
.. _git: http://git-scm.com/
.. _Eventlet: http://eventlet.net
.. _Gevent: http://gevent.org

View File

@ -1,9 +1,6 @@
template: doc.html
title: News
News
====
0.9.1 / 2010-05-26
------------------

117
doc/site/run.rst Normal file
View File

@ -0,0 +1,117 @@
template: doc.html
title: Run
.. contents::
:class: sidebar
:backlinks: top
Commands
--------
After installing Gunicorn you will have access to three command line scripts
that can be used for serving the various supported web frameworks:
* ``gunicorn``
* ``gunicorn_django``
* ``gunicorn_paster``
gunicorn
++++++++
The first and most basic script is used to serve 'bare' WSGI applications
that don't require a translation layer. Basic usage::
$ gunicorn [OPTIONS] APP_MODULE
Where ``APP_MODULE`` is of the pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``. The
module name can be a full dotted path. The variable name refers to a WSGI
callable that should be found in the specified module.
Example with test app::
$ cd examples
$ cat test.py
# -*- coding: utf-8 -
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
def app(environ, start_response):
"""Simplest possible application object"""
data = 'Hello, World!\n'
status = '200 OK'
response_headers = [
('Content-type','text/plain'),
('Content-Length', str(len(data)))
]
start_response(status, response_headers)
return iter([data])
$ gunicorn --workers=2 test:app
gunicorn_django
+++++++++++++++
You might not have guessed it, but this script is used to serve Django
applications. Basic usage::
$ gunicorn_django [OPTIONS] [SETTINGS_PATH]
By default ``SETTINGS_PATH`` will look for ``settings.py`` in the current
directory.
Example with your Django project::
$ cd path/to/yourdjangoproject
$ gunicorn_django --workers=2
gunicorn_paster
+++++++++++++++
Yeah, for Paster-compatible frameworks (Pylons, TurboGears 2, ...). We
apologize for the lack of script name creativity. And some usage::
$ gunicorn_paster [OPTIONS] paste_config.ini
Simple example::
$ cd yourpasteproject
$ gunicorn_paste --workers=2 development.ini
Integration
-----------
Alternatively, we also provide integration for both Django and Paster
applications in case your deployment strategy would be better served by such
invocation styles.
Django ./manage.py
++++++++++++++++++
You can add a ``run_gunicorn`` command to your ``./manage.py`` simply by adding
gunicorn to your ``INSTALLED_APPS``::
INSTALLED_APPS = (
...
"gunicorn",
)
Then you can run::
python manage.py run_gunicorn
paster serve
++++++++++++
If you're wanting to keep on keeping on with the usual paster serve command,
you can specify the Gunicorn server settings in your configuration file::
[server:main]
use = egg:gunicorn#main
host = 127.0.0.1
port = 5000
And then as per usual::
$ cd yourpasteproject
$ paster serve development.ini workers=2

View File

@ -1,189 +0,0 @@
template: doc.html
title: Command Line Usage
Usage
=====
After installing Gunicorn you will have access to three command line scripts
that can be used for serving the various supported web frameworks: ``gunicorn``,
``gunicorn_django``, and ``gunicorn_paster``.
Commonly Used Arguments
-----------------------
* ``-c CONFIG, --config=CONFIG`` - Specify the path to a `config file`_
* ``-b BIND, --bind=BIND`` - Specify a server socket to bind. Server sockets
can be any of ``$(HOST)``, ``$(HOST):$(PORT)``, or ``unix:$(PATH)``.
An IP is a valid ``$(HOST)``.
* ``-w WORKERS, --workers=WORKERS`` - The number of worker processes. This
number should generally be between 2-4 workers per core in the server.
Check the FAQ_ for ideas on tuning this parameter.
* ``-k WORKERCLASS, --worker-class=WORKERCLASS`` - The type of worker process
to run. You'll definitely want to read the `production page`_ for the
implications of this parameter. You can set this to ``egg:gunicorn#$(NAME)``
where ``$(NAME)`` is one of ``sync``, ``eventlet``, ``gevent``, or
``tornado``. ``sync`` is the default.
* ``-n APP_NAME, --name=APP_NAME`` - If setproctitle_ is installed you can
adjust the name of Gunicorn process as they appear in the process system
table (which affects tools like ``ps`` and ``top``).
There are various other parameters that affect user privileges, logging, etc.
You can see the complete list at the bottom of this page or as expected with::
$ gunicorn -h
gunicorn
--------
The first and most basic script is used to server 'bare' WSGI applications
that don't require a translation layer. Basic usage::
$ gunicorn [OPTIONS] APP_MODULE
Where ``APP_MODULE`` is of the pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``. The
module name can be a full dotted path. The variable name refers to a WSGI
callable that should be found in the specified module.
Example with test app::
$ cd examples
$ gunicorn --workers=2 test:app
gunicorn_django
---------------
You might not have guessed it, but this script is used to server Django
applications. Basic usage::
$ gunicorn_django [OPTIONS] [SETTINGS_PATH]
By default ``SETTINGS_PATH`` will look for ``settings.py`` in the current
directory.
Example with your Django project::
$ cd path/to/yourdjangoproject
$ gunicorn_django --workers=2
Alternatively, you can install some Gunicorn magic directly into your Django
project and use the provided command for running the server.
First you'll need to add ``gunicorn`` to your ``INSTALLED_APPS`` in the settings
file::
INSTALLED_APPS = (
...
"gunicorn",
)
Then you can run::
python manage.py run_gunicorn
gunicorn_paster
---------------
Yeah, for Paster-compatible frameworks (Pylons, TurboGears 2, ...). We
apologize for the lack of script name creativity. And some usage::
$ gunicorn_paster [OPTIONS] paste_config.ini
Simple example::
$ cd yourpasteproject
$ gunicorn_paste --workers=2 development.ini
If you're wanting to keep on keeping on with the usual paster serve command,
you can specify the Gunicorn server settings in your configuration file::
[server:main]
use = egg:gunicorn#main
host = 127.0.0.1
port = 5000
And then as per usual::
$ cd yourpasteproject
$ paster serve development.ini workers=2
Full Command Line Usage
-----------------------
::
$ gunicorn -h
Usage: gunicorn [OPTIONS] APP_MODULE
Options:
-c CONFIG, --config=CONFIG
Config file. [none]
-b BIND, --bind=BIND Adress to listen on. Ex. 127.0.0.1:8000 or
unix:/tmp/gunicorn.sock
-w WORKERS, --workers=WORKERS
Number of workers to spawn. [1]
-k WORKER_CLASS, --worker-class=WORKER_CLASS
The type of request processing to use
[egg:gunicorn#sync]
-p PIDFILE, --pid=PIDFILE
set the background PID FILE
-D, --daemon Run daemonized in the background.
-m UMASK, --umask=UMASK
Define umask of daemon process
-u USER, --user=USER Change worker user
-g GROUP, --group=GROUP
Change worker group
-n PROC_NAME, --name=PROC_NAME
Process name
--log-level=LOGLEVEL Log level below which to silence messages. [info]
--log-file=LOGFILE Log to a file. - equals stdout. [-]
--debug Debug mode. only 1 worker.
--spew Install a trace hook
--version show program's version number and exit
-h, --help show this help message and exit
Framework Examples
------------------
This is an incomplete list of examples of using Gunicorn with various
Python web frameworks. If you have an example to add you're very much
invited to submit a ticket to the `issue tracker`_ to have it included.
Itty
++++
Itty comes with builtin Gunicorn support. The Itty "Hello, world!" looks
like such::
from itty import *
@get('/')
def index(request):
return 'Hello World!'
run_itty(server='gunicorn')
Flask
+++++
Flask applications are WSGI compatible. Given this Flask app in an importable
Python module "helloflask.py"::
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
Gunicorn can then be used to run it as such::
$ gunicorn helloflask:app
Remember, if you're just trying to get things up and runnign that "importable"
can be as simple as "exists in the current directory".
.. _FAQ: faq.html
.. _`production page`: deployment.html
.. _`config file`: configuration.html
.. _setproctitle: http://pypi.python.org/pypi/setproctitle/
.. _`issue tracker`: http://github.com/benoitc/gunicorn/issues

View File

@ -4,40 +4,34 @@
<meta charset="utf-8" />
<title>Green Unicorn - {% block title %}Welcome{% endblock %}</title>
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<!--[if IE]>
<script>
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('nav');
document.createElement('time');
</script>
<![endif]-->
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
</head>
<body>
<div class="container">
<div id="header">
<h1 class="logo"><a href="http://gunicorn.org">gunicorn</a></h1>
<div id="links">
Get the source via
<a href="http://github.com/benoitc/gunicorn">git</a>, then
<a href="http://github.com/benoitc/gunicorn/issues">send feedback</a>
</div>
</div>
{% block extra %}{% endblock %}
{% block body %}{% endblock %}
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
<div class="container">
<div id="header">
<a href="./">
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
</a>
</div>
<div id="menu">
<ul id="actions">
<li><a href="install.html">Install</a></li>
<li><a href="run.html">Run</a></li>
<li><a href="configure.html">Configure</a></li>
<li><a href="deploy.html">Deploy</a></li>
<li><a href="design.html">Design</a><li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
</ul>
</div>
<div id="content">
{% block body %}{% endblock %}
</div>
<div id="footer">
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
<p>Hosted on <a href="http://github.com/">Github</a></p>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,11 +1,4 @@
{% extends "base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block body %}
{% include "menu.html" %}
{{ body }}
{% endblock %}
{% block toc %}{{ toc }}{% endblock %}
{% block body %}{{ body }}{% endblock %}

View File

@ -1,8 +1,2 @@
{% extends "base.html" %}
{% block body %}{{ body }}{% endblock %}
{% block extra %}
{% include "menu.html" %}
{% endblock %}
{% block body %}{{ body }}{% endblock %}

View File

@ -1,11 +0,0 @@
<div id="menu">
<ul id="actions">
<li><a href="installation.html">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="deployment.html">Deployment</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="tuning.html">Tuning</a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="news.html">News</a></li>
</ul>
</div>

View File

@ -0,0 +1,11 @@
# Run with:
#
# $ gunicorn flaskapp:app
#
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"

View File

@ -0,0 +1,12 @@
# Run with:
#
# $ python ittyapp.py
#
from itty import *
@get('/')
def index(request):
return 'Hello World!'
run_itty(server='gunicorn')

View File

Before

Width:  |  Height:  |  Size: 339 B

After

Width:  |  Height:  |  Size: 339 B

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -3,6 +3,10 @@
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
#
# Run with:
#
# $ gunicorn -k egg:gunicorn#tornado tornadoapp:app
#
import tornado.web

View File

@ -197,7 +197,7 @@ def validate_callable(arity):
return _validate_callable
with Setting("config") as s:
s.section = "Config"
s.section = "Config File"
s.cli = ["-c", "--config"]
s.meta = "FILE"
s.validator = validate_string
@ -205,9 +205,6 @@ with Setting("config") as s:
s.fmt_desc("""\
The path to a Gunicorn config file.
By default Gunicorn will try to read a file named 'gunicorn.conf.py' in
the current directory.
Only has an effect when specified on the command line or as part of an
application specific configuration.
""")
@ -268,7 +265,7 @@ with Setting("worker_class") as s:
The type of workers to use.
The default async class should handle most 'normal' types of work loads.
You'll want to read http://gunicorn/deployment.hml for information on
You'll want to read http://gunicorn.org/design.hml for information on
when you might want to choose one of the other worker classes.
An string referring to a 'gunicorn.workers' entry point or a
@ -277,10 +274,10 @@ with Setting("worker_class") as s:
The default provided values are:
* egg:gunicorn#sync
* egg:gunicorn#eventlet - Requires eventlet >= 0.9.7
* egg:gunicorn#gevent - Requires gevent >= 0.12.2 (?)
* egg:gunicorn#tornado - Requires tornado >= 0.2
* ``egg:gunicorn#sync``
* ``egg:gunicorn#eventlet`` - Requires eventlet >= 0.9.7
* ``egg:gunicorn#gevent`` - Requires gevent >= 0.12.2 (?)
* ``egg:gunicorn#tornado`` - Requires tornado >= 0.2
""")
with Setting("worker_connections") as s:
@ -393,27 +390,29 @@ with Setting("pidfile") as s:
with Setting("user") as s:
s.section = "Server Mechanics"
s.cli = ["-u", "--user"]
s.meta = "USER"
s.validator = validate_string
s.default = None
s.fmt_desc("""\
Switch worker processes to run as this user.
A valid user id (as an integer) or the name of a user that can be
retrieved with a call to pwd.getpwnam(value) or None to not change the
worker process user.
retrieved with a call to pwd.getpwnam(value) or None to not change
the worker process user.
""")
with Setting("group") as s:
s.section = "Server Mechanics"
s.cli = ["-g", "--group"]
s.meta = "GROUP"
s.validator = validate_string
s.default = None
s.fmt_desc("""\
Switch worker process to run as this group.
A valid group id (as an integer) or the name of a user that can be
retrieved with a call to pwd.getgrnam(value) or None to change the
worker processes group.
retrieved with a call to pwd.getgrnam(value) or None to not change
the worker processes group.
""")
with Setting("umask") as s:
@ -487,9 +486,10 @@ with Setting("proc_name") as s:
s.fmt_desc("""\
A base to use with setproctitle for process naming.
This affects things like 'ps' and 'top'. If you're going to be running
more than one instance of Gunicorn you'll probably want to set a name to
tell them apart. This requires that you install the setproctitle module.
This affects things like ``ps`` and ``top``. If you're going to be
running more than one instance of Gunicorn you'll probably want to set a
name to tell them apart. This requires that you install the setproctitle
module.
It defaults to 'gunicorn'.
""")