gunicorn/doc/htdocs/deployment.html
2010-05-06 14:05:22 -04:00

208 lines
7.5 KiB
HTML

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