Apr 17
web2py behind apache with mod_wsgi part II: mod_rewrite rules
Ok, in the previous post I’ve shown a way to run web2py behind apache using mod_wsgi.
The main “problem” still to be addressed is: URIs. Assume you have 3 website which implies (in the common case) 3 web2py application,
- www.primo.it with the we2bpy app called primo
- www.secondo.it , appname is secondo
- www.terzo.it, appname is terzo.
(ok, maybe I lack of fantasy … )
Now we ended up having a vhost with
ServerName web2py.localhost
so all of our 3 applications are at
web2py.localhost/primo/default/index, web2py.localhost/secondo/default/index, web2py.localhost/terzo/default/index. It should work, but it’s not what we want.
The simplest thing here is to add
ServerAlias www.primo.it www.secondo.it www.terzo.it
to the vhost conf file. This works, but has a couple of disadvantages:
- application name is still in the url (i.e. www.primo.it/primo/default/index)
- secondo and terzo are available from primo’s url and vice-versa (www.primo.it/secondo/default/index shows secondo application)
Here enters mod_rewrite. Leave the ServerAlias in place, as they are needed.
Disclaimer I’m **NOT** a mod_rewrite guru -as you’ll see-, and I really think that there are better ways to accomplish this task: suggestions are welcome ^^
Starting with www.primo.it, add this at the beginning of the vhost file, just after the DocumentRoot directive:
RewriteEngine On
RewriteCond %{HTTP_HOST} =www.primo.it [NC, OR]
RewriteCond %{HTTP_HOST} =primo.it [NC]
RewriteRule /primo/(.*) /$1 [N]
RewriteCond %{HTTP_HOST} =www.primo.it [NC, OR]
RewriteCond %{HTTP_HOST} =primo.it [NC]
RewriteRule ^/(.*) /primo/$1 [PT,L]
The first “block” is needed to fix “links” in web2py applications, so that if you are using URL() function it continues to work. The problem it addresses is that we don’t want application name in URLs buth URL() keeps adding it. So we remove it; the [N] flag after the first RewriteRule means “restart from the beginning after applying” (the downside is that this is an external redirect
)
The second “block” is needed to do the actual work: it transparently add the app name to the request, but the url in user browser remains without. So one user accessing www.primo.it/default/index arrives to wsgi as if he/she was calling www.primo.it/primo/default/index (and the user still have www.primo.it/default/index) in his/her location bar. The [L] flags means “last” (i.e. stop processing rewrites) and [PT] means “jump directly to the next alias handler”, which is the WSGIScriptAlias defined in previous posts.
Repeat this two blocks (RewriteEngine On is needed only the first time) for every application you have (you can do includes in separate files if you wish) and you end up having
- www.primo.it that redirect to www.primo.it/default/index.
- www.primo.it/secondo/default/index still working
- web2py.localhost/primo/default/index still working
- https (i.e. management) only on web2py.localhost. If you want https support for primo.it you should add the rewrite rules event to the https section, (or -better- include two times the same file)
Hope this helps… and if you have better options or ideas write a comment
Last thing about the RewriteCond: yes, I already know that it can be done with a regex instead of using the =www.primo.it AND rewriting the condition without www. but I like this way far more as it’s simpler and much more understandable.

April 18th, 2009 at 1:37 am
Thanks so much for the second writeup! Super useful, the only snag I’ve hit is in the apache virtual hosts file doesn’t resolve to the application (/appname/index), it always always goes to the default application (/default/index). As I don’t have much Apache config experience, I may be missing something obvious. My config file is pretty much identical to yours, any chance we could get a peek at the new config file which includes multiple apps?
Your assistance has been greatly appreciated
Cheers.
-Seth
April 18th, 2009 at 7:49 am
Well, apache resolv http://www.domain.tld/ to http://www.domain.tld/appname/, then it’s up to web2py and it resolv /appname/ to /appname/default/index.
If you want a different default route you should check the routes_in parameter of web2py.
Here there’s some doc about it http://www.web2py.com/AlterEgo/default/show/42
September 21st, 2009 at 3:49 pm
Thanks for this nice tutorial! I tried the .htaccess but I got a 500 error.
Any ideas?
September 21st, 2009 at 4:16 pm
watch the apache error_log, you’ll find an explanation of the problem. Can be permission-related, some misconfiguration or something not considered when I was writing this tutorial
and, yes, set the RewriteLog and watch what’s happening there too..
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritelog
September 21st, 2009 at 8:32 pm
Thanks for your reply! I am getting:
RewriteCond: bad flag delimiters
September 22nd, 2009 at 8:16 am
can you post the rewrite rule?
September 22nd, 2009 at 9:34 am
RewriteEngine On
RewriteCond %{HTTP_HOST} =www.mydomain.com [NC, OR]
RewriteCond %{HTTP_HOST} =mydomain.com [NC]
RewriteRule /mydomain/(.*) /$1 [N]
RewriteCond %{HTTP_HOST} =www.mydomain.com [NC, OR]
RewriteCond %{HTTP_HOST} =mydomain.com [NC]
RewriteRule ^/(.*) /mydomain/$1 [PT,L]
RewriteRule ^dispatch\.fcgi/ – [L]
RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]
This is the whole .htaccess
September 22nd, 2009 at 11:00 am
seems ok, but are you sure RewriteRule ^dispatch\.fcgi/ – [L] is correct?
September 22nd, 2009 at 11:37 am
RewriteRule ^dispatch\.fcgi/ – [L]
seems to work
but I get ‘RewriteCond: bad flag delimiters’ from the RewriteCond
September 22nd, 2009 at 12:03 pm
could be that you have a non-unix line feed. If the server is linux and you use windows please use a text-editor that permit you to set the line feeds type.
Or could be a space left in the rewrite cond.
Sorry, just guessing here… try google for the error and see what happens.
September 22nd, 2009 at 6:20 pm
Thanks a lot for your help. I am writing it on linux. I am googling and I’ve even added a question at stackoverflow and serverfault.com. It’s definitely something wrong with my spaces
Thank again!
September 22nd, 2009 at 7:03 pm
After a lot of fiddling around and posting around the internet:
http://stackoverflow.com/questions/1454384/htaccess-transparently-adding-a-name-to-the-request
http://serverfault.com/questions/67615/htaccess-transparently-adding-a-name-to-the-request
I think that the problem is the added space between parameters (like [NC, OR]).
Now, it doesn’t throw an error but when I am hitting the domain, it redirects to http://mydomain.com/welcome/default/index (is it ignoring it?)
September 22nd, 2009 at 7:20 pm
sorry, I didn’t notice the space between flags
looking at your .htaccess you are using PT flag but you don’t have a Alias/ScriptAlias/WSGIScriptAlias so, yes, I think it’s ignoring the rewrite rule
Look here for more info on PT flag: http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule
September 22nd, 2009 at 8:31 pm
So, what has to be added to your code to make it ok? I don’t think removing [PT] solves the problem
RewriteEngine On
RewriteCond %{HTTP_HOST} =www.primo.it [NC,OR]
RewriteCond %{HTTP_HOST} =primo.it [NC]
RewriteRule /primo/(.*) /$1 [N]
RewriteCond %{HTTP_HOST} =www.primo.it [NC,OR]
RewriteCond %{HTTP_HOST} =primo.it [NC]
RewriteRule ^/(.*) /primo/$1 [PT,L]
September 22nd, 2009 at 8:49 pm
look at the previous post http://jdoe.asidev.com/2009/02/26/configure-web2py-to-run-behind-apache-with-wsgi-mod_wsgi/
You need a WSGIScriptAlias or ScriptAlias for this to work
September 22nd, 2009 at 11:19 pm
But what happens when you are on a shared hosting environment? (I am trying for the past two days to write a full tutorial on how to install and setup web2py on shared hosting accounts. IF I ever gather all the info, you’ll get a HUGE HUGE HUGE thanks-and a link of course).
Thanks again for all the help (I can’t believe it’s THAT difficult to run web2py on shared account)
September 23rd, 2009 at 8:35 am
uhm, maybe this email can be of help? are you using fcgi or wsgi? http://www.mail-archive.com/modwsgi@googlegroups.com/msg00499.html