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

 
  1. joernwuv605954 reblogged this from sbglasius
  2. sbglasius posted this
Blog comments powered by Disqus