Pylons Via Apache Port Issues
I’ve been using Pylons (and, more recently, the Pylons-based TurboGears 2.0) for various projects for a while, and a few weeks ago ran into an annoying and specific problem: using Pylons via Apache made Pylons occasionally think it was running on a different port.
There’s a relatively easy answer to this, but until I was reading through TurboGears documentation, I didn’t find it.
The basic setup is this: I’m running my Pylons project on some arbitrary port, and I want to point some URL that Apache knows about from port 80 to that arbitrary port. I use a RewriteRule to do this, as follows.
Pylons development.ini:
[server:main] use = egg:Paste#http host = sub.server.tld port = 12345
apache.conf:
<VirtualHost *:80> ServerName sub.server.tld RewriteEngine On RewriteRule ^/(.*) http://sub.server.tld:12345/$1 [P] DocumentRoot /path/to/pylons/project </VirtualHost>
All that does is have Apache look for incoming port 80 requests to that subdomain and then pass them to that subdomain on port 12345, which is where the Pylons app is listening.
That works just fine until, for any reason, you have your Pylons project execute a local redirect, e.g. redirect("/nextpage/")
. At this point Pylons will tell the browser to go to http://sub.server.tld:12345/nextpage/
, which for me caused all kinds of problems.
Embarrassingly, I couldn’t find the answer to this problem, despite looking through everything I could find about where Pylons sets its host name and port in the environment, etc.
When I was setting up TurboGears 2, however, I noticed a reference to using TurboGears behind Apache as a reverse proxy, and instructions on doing that. The RewriteRule above is essentially doing exactly that, but I hadn’t thought of it in those terms. The reverse proxy instructions included how to deal with the port issues. There were a couple of further hiccups, but I ultimately got it working.
The Apache configuration stays the same, as does the server:main
section of development.ini. Change the title of the app:main
section to app:pylons
. Then add the following to development.ini:
[pipeline:main] pipeline = proxy pylons [filter:proxy] use = egg:PasteDeploy#prefix prefix = / force_port:80
That’s it; pipeline
tells it to run through proxy before running the pylons section (which is what used to be your app:main
section), and the filter:proxy
section tells it to force the port to 80.
The only other thing to remember is that now you have to run
paster setup-app development.ini#pylons
instead of
paster setup-app development.ini
(Note that this is for small or in-development projects only—if you’re going to be running anything that requires better performance, paster behind an Apache Rewrite is probably not the way to go.)
02 Mar 2011 at 20:33
Thanks man. This post is a life saver. I was trying to setup proxypass for the apache but rewrite works much better.
09 May 2011 at 20:56
apache.conf:
ProxyPreserveHost on
…
Requires mod_proxy but you need it for a RewriteRule [P] proxy anyway. Hope it works for someone else who Googled here.