Grails, Weceem and Apache2
I have been using most of my day getting the GR8Conf websites running on the new server.
Let me tell you, it was not trivial, but I managed to get it working (and working GR8 too).
The setup:
A Weceem application running in the context /gr8confcms
A Tomcat 6 server
A MySql server instance (not important here)
An Apache2 server running on a Ubuntu server
The plan:
I want to run all the GR8Conf websites in one Weceem application, using the Weceem spaces (one war)
gr8conf.org should be the default space in Weceem
I want gr8conf.eu and gr8conf.us to be two other spaces in Weceem
The old gr8conf websites from previous years (two wars) should be accessible as 2010.gr8conf.eu and 2011.gr8conf.eu
I want the url's to look as if they do not run under a certain context, but as root.
The admin-part of the application should work as well (the Cookie path should be correct).
I don't want to make changes in the Tomcat server.xml file
I want to be able to deploy via the Tomcat manager interface or directly from Grails using the tomcat target.
After reading numerous blog-posts about configuration of Tomcat and Apache, I found a setup that works. Thats the good part, the bad part is, that it requires quite some configuration on the Apache side.
Requirements:
Apache webserver with the following modules enabled:
mod_proxy
mod_proxy_html
mod_rewrite
mod_headers
Tomcat 6 (or 7)
Installing those modules should be pretty straight forward using apt-get and a2enmod.
First thing to get working: gr8conf.org
I could not avoid changing the Tomcat server.xml, as I want to use AJP. Uncomment this section in the server.xml
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
Now I made a new file in /etc/apache/sites-available called gr8conf.org with this content:
<VirtualHost *:80> ServerName gr8conf.org ServerAlias www.gr8conf.org LogLevel warn ErrorLog /var/log/apache2/gr8conf_org-error.log CustomLog /var/log/apache2/gr8conf_org-access.log combined ProxyRequests Off ProxyPreserveHost On RewriteEngine On <Proxy *> AddDefaultCharset off Order deny,allow Allow from all </Proxy> # redirect request if user is using an alias for this server RewriteCond "%{HTTP_HOST}" "!^gr8conf.org$" RewriteRule "^(.*)$" "http://gr8conf.org$1" [L,R=301] # redirect stray requests to the correct url (*1) RewriteRule "/gr8confcms/(.*)$" "http://gr8conf.org/$1" [L,NE] # edit the location header, to match the correct path (*2) Header edit Location "^http://gr8conf.org/gr8confcms/(.*)$" "http://gr8conf.org/$1" # edit the cookie path to match the correct location, otherwise it will not be stored in the browser Header edit Set-Cookie "^(.*); Path=/gr8confcms$" "$1; Path=/" # the actual proxy ProxyPass / ajp://localhost:8009/gr8confcms/ ProxyPassReverse / ajp://localhost:8009/gr8confcms/ # rewrite links to css and javascript SetOutputFilter DEFLATE;proxy-html;INFLATE ProxyHTMLExtended On ProxyHtmlURLMap /gr8confcms/ / # The doctype is set to Legacy to avoid stripping of iframe links (*3) ProxyHTMLDoctype HTML Legacy </VirtualHost>
I hope the comments speaks pretty much for themself.
The thing that took the most time to figure out, was how to handle Spring Security login, storing the cookie in the right place. I did try to use ProxyPassReverseCookieDomain and ProxyPassReverseCookiePath, but could not get it working. When I started to rewrite the header instead it worked instantly (see *2).
While working with the Cookie, I also noticed that the URL with the 'jsessionid' was being escaped, so I put the [NE] option in the RewriteRule (see *1)
The last thing to notice is, that mod_proxy_html would strip information from any iframes (I needed those), and to avoid that, I added the 'Legacy' to ProxyHTMLDoctype.
Finally I add it to the apache configuration:
sudo a2ensite gr8conf.org
Now that I got the first site working, the next was pretty straight forward.
Getting the gr8conf.eu site working:
I made a second file in /etc/apache/sites-available called gr8conf.eu with this content:
<VirtualHost *:80> ServerName gr8conf.eu ServerAlias www.gr8conf.eu LogLevel warn ErrorLog /var/log/apache2/gr8conf_eu-error.log CustomLog /var/log/apache2/gr8conf_eu-access.log combined ProxyRequests Off ProxyPreserveHost On RewriteEngine On AddDefaultCharset off Order deny,allow Allow from all # redirect request if user is using an alias for this server RewriteCond "%{HTTP_HOST}" "!^gr8conf.eu$" RewriteRule "^(.*)$"" "http://gr8conf.eu$1" [L,R=301] # If hitting the root, redirect to the index page RewriteRule "^/$" "http://gr8conf.eu/index" [L] # The url's for uploads are handled by the gr8conf.org configuration RewriteRule "/gr8confcms/uploads/(.*)$" "http://gr8conf.org/uploads/$1" [L] # The admin page is handled by the gr8conf.org configuration (It's not the actual URL....) RewriteRule "/admin" "http://gr8conf.org/admin" [L,R=301] RewriteRule "/gr8confcms/(.*)$" "http://gr8conf.eu/$1" [L,NE] Header edit Location "^http://gr8conf.eu/gr8confcms/(.*)$" "http://gr8conf.eu/$1" Header edit Set-Cookie "^(.*); Path=/gr8confcms$" "$1; Path=/" # The proxy is now pointing to the url of the EU-2012 space in Weceem ProxyPass / ajp://localhost:8009/gr8confcms/content/eu2012/ ProxyPassReverse / ajp://localhost:8009/gr8confcms/content/eu2012/ SetOutputFilter INFLATE;proxy-html;DEFLATE ProxyHTMLExtended On ProxyHtmlURLMap /gr8confcms/content/eu2012/ / ProxyHTMLDoctype XHTML Legacy </VirtualHost>
I have highlighted the major changes compared to the setup for gr8conf.org, no need to elaborate further on the comments.
The configuration for the old sites (2011.gr8conf.eu) follows the same recipe.
I think this pretty much covers it... I'm not an Apache expert, but with with weights and pulleys I managed to get it running smoothly.
If you find any flaws in my setup, or is it possible ot make it simpler, please let me know!
/Søren












