Tuesday, 2 October 2007

Developing with Grails and Apache2

In production I use Apache2 in front of Tomcat. The configuration for this is quite simple and standard. However, while developing Grails applications I wanted to run the same configuration, so that there are very few differences between my development and production environments. In Apache, I use named virtual hosts to forward to Tomcat, and Tomcat is configured with web applications corresponding to the virtual host name, with just '/' as the context path.

Grails uses Jetty, and when running 'grails run-app' a Jetty container is configured and started. This is fine for me, I don't think I really need to switch to Tomcat in development, but running Apache2 in front of it would be very nice. This way I don't need to worry about differences in URLs.

I'm not familiar with Jetty at all, so the simplest and fastest way to get this working was to make a copy of the RunApp.groovy script that comes with Grails and change it so that it looks for the context path definition in 'application.properties' in the root of the Grails project.

Update March 7 2008:
See the comments below - I have produced a better implementation:

- appContext is now defined in Init.groovy so it is available to all scripts
- RunApp.groovy and RunWar.groovy use the appContext to configure the server and display the url.
- RunAppHttps.groovy reuses RunApp.groovy so the only change here is for displaying the url.

This is now raised in JIRA as an enhancement.

So, in $GRAILS_HOME/scripts/RunApp.groovy add the following after the 'includeTargets' directive:

def props = Ant.antProject.properties
def appContext = props.'app.context' ? props.'app.context' : grailsAppName
if(!appContext.startsWith('/')) {
appContext = "/${appContext}"

Now change the webContext definition:
webContext = new WebAppContext("${basedir}/web-app", "${appContext}")

For completeness, update the StatusFinal event:
event("StatusFinal", ["Server running. Browse to http://localhost:$serverPort$appContext"])

Each Grails project has an application.properties file in the root of the project. If you want to change the context path from the default, define it in this properties file like so:

Now your application can be viewed at http://localhost:8080/<app.context>, or, with Apache in front of it, http://virtualhostname/<app.context>.

In my case I want to set the context path to merely '/' so in application.properties I define:

And with Apache2 configured properly, I view my application at http://virtualhostname/.

Download the modified Grails 0.6 RunApp.groovy here.

Download the modified Grails 1.0-RC1 RunApp.groovy here.

Download the modified Grails 1.0-RC2 RunApp.groovy here.

Download the modified Grails 1.0-RC3 RunApp.groovy here.

Download the modified Grails 1.0 RunApp.groovy here.

Download the modified Grails 1.0.1 scripts here: grails-1.0.1-context-path-mod.tar.gz