/usr/share/doc/python-twisted-web2/howto/deployment.html is in python-twisted-web2 8.1.0-3build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | <?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: Twisted.web2 Deployment</title><link href="stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">Twisted.web2 Deployment</h1><div class="toc"><ol><li><a href="#auto0">Standalone HTTP</a></li><li><a href="#auto1">HTTP behind Apache2</a></li><li><a href="#auto2">HTTP behind Apache1</a></li><li><a href="#auto3">SCGI</a></li><li><a href="#auto4">FastCGI</a></li><li><a href="#auto5">CGI</a></li></ol></div><div class="content"><span></span><p>There are a number of possibilities for deploying twisted.web2:
as standalone HTTP[S] server, HTTP proxied behind another server,
SCGI, FastCGI, or CGI.</p><p>Deploying as a standalone HTTP/HTTPS server is by far the
simplest. Unless you have a reason not to, it is recommended that
you choose this option. However, many people already run web
servers on their computer and are not willing or able to
completely blow it away and replace it with twisted.web2. The next
best option is to run twisted.web2 as a server proxied behind your
existing webserver, using either HTTP or SCGI.</p><h2>Standalone HTTP<a name="auto0"></a></h2><p>For completeness, here is a simple standalone HTTP server again.</p><div class="py-listing"><pre>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web2</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">server</span>, <span class="py-src-variable">channel</span>, <span class="py-src-variable">static</span>
<span class="py-src-comment"># For example, serve the /tmp directory
</span><span class="py-src-variable">toplevel</span> = <span class="py-src-variable">static</span>.<span class="py-src-variable">File</span>(<span class="py-src-string">"/tmp"</span>)
<span class="py-src-variable">site</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">toplevel</span>)
<span class="py-src-comment"># Start up the server
</span><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">service</span>, <span class="py-src-variable">strports</span>
<span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">"demoserver"</span>)
<span class="py-src-variable">s</span> = <span class="py-src-variable">strports</span>.<span class="py-src-variable">service</span>(<span class="py-src-string">'tcp:8080'</span>, <span class="py-src-variable">channel</span>.<span class="py-src-variable">HTTPFactory</span>(<span class="py-src-variable">site</span>))
<span class="py-src-variable">s</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">application</span>)
</pre><div class="caption">
Listing 1: A standalone HTTP server - <a href="../examples/deployment/standalone.tac"><span class="filename">../examples/deployment/standalone.tac</span></a></div></div><h2>HTTP behind Apache2<a name="auto1"></a></h2><p>If you use HTTP proxying, you must inform twisted.web2 of the
real URL it is being accessed by, or else any URLs it generates
will be incorrect. You can do this via the AutoVHostURIRewrite
resource when using apache2 as the main server.</p><p>On the apache side, configure as follows. Apache automatically
sends the original host in the X-Forwarded-Host header, and the
original remote IP address in the X-Forwarded-For header. You must
additionally send along the original path, and the original
scheme.</p><p>For proxying a subdirectory:</p><pre>
<Location /whatever/>
ProxyPass http://localhost:8538/
RequestHeader set X-App-Location /whatever/
RequestHeader set X-App-Scheme http
</Location>
</pre><p>Or, for serving an entire HTTPS virtual host:</p><pre>
<VirtualHost myip:443>
ServerName example.com
ProxyPass / http://localhost:8538/
RequestHeader set X-App-Location /
RequestHeader set X-App-Scheme https
</VirtualHost>
</pre><p>Now, on the twisted.web2 side</p><div class="py-listing"><pre>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web2</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">server</span>, <span class="py-src-variable">channel</span>, <span class="py-src-variable">static</span>, <span class="py-src-variable">vhost</span>
<span class="py-src-comment"># For example, serve the /tmp directory
</span><span class="py-src-variable">toplevel</span> = <span class="py-src-variable">static</span>.<span class="py-src-variable">File</span>(<span class="py-src-string">"/tmp"</span>)
<span class="py-src-comment"># Use the automatic uri rewriting based on apache2 headers
</span><span class="py-src-variable">toplevel</span> = <span class="py-src-variable">vhost</span>.<span class="py-src-variable">AutoVHostURIRewrite</span>(<span class="py-src-variable">toplevel</span>)
<span class="py-src-variable">site</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">toplevel</span>)
<span class="py-src-comment"># Start up the server
</span><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">service</span>, <span class="py-src-variable">strports</span>
<span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">"demoserver"</span>)
<span class="py-src-variable">s</span> = <span class="py-src-variable">strports</span>.<span class="py-src-variable">service</span>(<span class="py-src-string">'tcp:8538'</span>, <span class="py-src-variable">channel</span>.<span class="py-src-variable">HTTPFactory</span>(<span class="py-src-variable">site</span>))
<span class="py-src-variable">s</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">application</span>)
</pre><div class="caption">
Listing 2: Behind Apache 2 - <a href="../examples/deployment/apache2.tac"><span class="filename">../examples/deployment/apache2.tac</span></a></div></div><h2>HTTP behind Apache1<a name="auto2"></a></h2><p>Apache 1 doesn't provide the X-Forwarded-Host or
X-Forwarded-For headers, or the ability to set custom headers in
the outgoing proxy request. Therefore, you must provide that
information to twisted.web2 directly. This is accomplished by the
VHostURIRewrite resource.</p><p>Setup apache as follows:</p><pre>
<VirtualHost myip>
ServerName example.com
ProxyPass /foo/ http://localhost:8538/
</VirtualHost>
</pre><p>And twisted like so</p><div class="py-listing"><pre>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web2</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">server</span>, <span class="py-src-variable">channel</span>, <span class="py-src-variable">static</span>, <span class="py-src-variable">vhost</span>
<span class="py-src-comment"># For example, serve the /tmp directory
</span><span class="py-src-variable">toplevel</span> = <span class="py-src-variable">static</span>.<span class="py-src-variable">File</span>(<span class="py-src-string">"/tmp"</span>)
<span class="py-src-comment"># Add the rewriter.
</span><span class="py-src-variable">toplevel</span> = <span class="py-src-variable">vhost</span>.<span class="py-src-variable">VHostURIRewrite</span>(<span class="py-src-string">"http://myhostname.com/foo/"</span>, <span class="py-src-variable">toplevel</span>)
<span class="py-src-variable">site</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">toplevel</span>)
<span class="py-src-comment"># Start up the server
</span><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">service</span>, <span class="py-src-variable">strports</span>
<span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">"demoserver"</span>)
<span class="py-src-variable">s</span> = <span class="py-src-variable">strports</span>.<span class="py-src-variable">service</span>(<span class="py-src-string">'tcp:8538:interface=127.0.0.1'</span>, <span class="py-src-variable">channel</span>.<span class="py-src-variable">HTTPFactory</span>(<span class="py-src-variable">site</span>))
<span class="py-src-variable">s</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">application</span>)
</pre><div class="caption">
Listing 3: Behind Apache 1 - <a href="../examples/deployment/apache1.tac"><span class="filename">../examples/deployment/apache1.tac</span></a></div></div><p>Because vhost.VHostURIRewrite can exist anywhere in the
resource tree, you can have multiple applications running on a
single twisted port by making them siblings of a root resource and
referencing their full path in the ProxyPass directive.</p><p>Setup apache as follows:</p><pre>
<VirtualHost foo.myhostname.com>
ProxyPass / http://localhost:8538/foo/
ServerName example.com
</VirtualHost>
<VirtualHost bar.myhostname.com>
ProxyPass / http://localhost:8538/bar/
ServerName example.com
</VirtualHost>
</pre><p>And twisted like so</p><div class="py-listing"><pre>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web2</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">server</span>, <span class="py-src-variable">channel</span>, <span class="py-src-variable">resource</span>, <span class="py-src-variable">static</span>, <span class="py-src-variable">vhost</span>
<span class="py-src-comment"># For example, server the /tmp/foo directory
</span><span class="py-src-variable">foo_toplevel</span> = <span class="py-src-variable">static</span>.<span class="py-src-variable">File</span>(<span class="py-src-string">"/tmp/foo"</span>)
<span class="py-src-comment"># And the /tmp/bar directory
</span><span class="py-src-variable">bar_toplevel</span> = <span class="py-src-variable">static</span>.<span class="py-src-variable">File</span>(<span class="py-src-string">"/tmp/bar"</span>)
<span class="py-src-comment"># Add the rewriters:
</span><span class="py-src-variable">foo_toplevel</span> = <span class="py-src-variable">vhost</span>.<span class="py-src-variable">VHostURIRewrite</span>(<span class="py-src-string">"http://foo.myhostname.com/"</span>,
<span class="py-src-variable">foo_toplevel</span>)
<span class="py-src-variable">bar_toplevel</span> = <span class="py-src-variable">vhost</span>.<span class="py-src-variable">VHostURIRewrite</span>(<span class="py-src-string">"http://bar.myhostname.com/"</span>,
<span class="py-src-variable">bar_toplevel</span>)
<span class="py-src-variable">toplevel</span> = <span class="py-src-variable">resource</span>.<span class="py-src-variable">Resource</span>()
<span class="py-src-variable">toplevel</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">'foo'</span>, <span class="py-src-variable">foo_toplevel</span>)
<span class="py-src-variable">toplevel</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">'bar'</span>, <span class="py-src-variable">bar_toplevel</span>)
<span class="py-src-variable">site</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">toplevel</span>)
<span class="py-src-comment"># Start up the server
</span><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">service</span>, <span class="py-src-variable">strports</span>
<span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">"demoserver"</span>)
<span class="py-src-variable">s</span> = <span class="py-src-variable">strports</span>.<span class="py-src-variable">service</span>(<span class="py-src-string">'tcp:8538:interface=127.0.0.1'</span>, <span class="py-src-variable">channel</span>.<span class="py-src-variable">HTTPFactory</span>(<span class="py-src-variable">site</span>))
<span class="py-src-variable">s</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">application</span>)
</pre><div class="caption">
Listing 4: Multiple hosts behind Apache 1 - <a href="../examples/deployment/apache1_twohosts.tac"><span class="filename">../examples/deployment/apache1_twohosts.tac</span></a></div></div><h2>SCGI<a name="auto3"></a></h2><p>SCGI is an alternative to HTTP proxying. SCGI should work
instead of HTTP proxying from servers which support
it. Additionally, if all you have access to from the web server is
CGI, but are able to run long-running processes, you can use
the <a href="http://www.mems-exchange.org/software/scgi/scgi-1.2.tar.gz/scgi-1.2/cgi2scgi.c">cgi2scgi</a>
C program to channel CGI requests to your twisted.web2 SCGI
port. This won't be as efficient as mod_scgi or http proxying, but
it will be much better than using twisted directly as a CGI.</p><p>FIXME:Someone who has installed mod_scgi in apache should write
a bit on it.</p><p>Configure Twisted as follows</p><div class="py-listing"><pre>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web2</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">server</span>, <span class="py-src-variable">channel</span>, <span class="py-src-variable">static</span>
<span class="py-src-comment"># For example, serve the /tmp directory
</span><span class="py-src-variable">toplevel</span> = <span class="py-src-variable">static</span>.<span class="py-src-variable">File</span>(<span class="py-src-string">"/tmp"</span>)
<span class="py-src-variable">site</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">toplevel</span>)
<span class="py-src-comment"># Start up the server
</span><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">service</span>, <span class="py-src-variable">strports</span>
<span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">"demoserver"</span>)
<span class="py-src-variable">s</span> = <span class="py-src-variable">strports</span>.<span class="py-src-variable">service</span>(<span class="py-src-string">'tcp:3000'</span>, <span class="py-src-variable">channel</span>.<span class="py-src-variable">SCGIFactory</span>(<span class="py-src-variable">site</span>))
<span class="py-src-variable">s</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">application</span>)
</pre><div class="caption">
Listing 5: An SCGI Server - <a href="../examples/deployment/scgi.tac"><span class="filename">../examples/deployment/scgi.tac</span></a></div></div><h2>FastCGI<a name="auto4"></a></h2><p>FastCGI is another popular way to run a web application. Blah blah.</p><h2>CGI<a name="auto5"></a></h2><p>CGI is the worst possible deployment environment, yet in some
cases it may be all that is possible. It allows only a single
request to be served from a process, so any kind of in-memory
storage is impossible. Also, the overhead of starting up a new
python interpreter for every request can get quite high. You
should only consider using it if your hosting provider does not
allow you to keep a process running.</p><p>However, if it's your only choice, you can deploy a
twisted.web2 app using it. Unlike the other examples, where we
create a .tac file for running with twistd, in this case, a
standalone python script is necessary</p><pre class="python">
<span class="py-src-comment">#!/usr/bin/env python
</span> <span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web2</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">channel</span>, <span class="py-src-variable">server</span>, <span class="py-src-variable">static</span>
<span class="py-src-variable">toplevel</span> = <span class="py-src-variable">static</span>.<span class="py-src-variable">File</span>(/<span class="py-src-variable">tmp</span>)
<span class="py-src-variable">site</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">toplevel</span>)
<span class="py-src-variable">channel</span>.<span class="py-src-variable">startCGI</span>(<span class="py-src-variable">site</span>)
</pre></div><p><a href="index.html">Index</a></p><span class="version">Version: 8.1.0</span></body></html>
|