21 Deployment - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari
Version: 2.5.1
21 Deployment
Grails applications can be deployed in a number of ways, each of which has its pros and cons."grails run-app"
You should be very familiar with this approach by now, since it is the most common method of running an application during the development phase. An embedded Tomcat server is launched that loads the web application from the development sources, thus allowing it to pick up an changes to application files.This approach is not recommended at all for production deployment because the performance is poor. Checking for and loading changes places a sizable overhead on the server. Having said that,grails prod run-app
removes the per-request overhead and lets you fine tune how frequently the regular check takes place.Setting the system property "disable.auto.recompile" to true
disables this regular check completely, while the property "recompile.frequency" controls the frequency. This latter property should be set to the number of seconds you want between each check. The default is currently 3."grails run-war"
This is very similar to the previous option, but Tomcat runs against the packaged WAR file rather than the development sources. Hot-reloading is disabled, so you get good performance without the hassle of having to deploy the WAR file elsewhere.WAR file
When it comes down to it, current java infrastructures almost mandate that web applications are deployed as WAR files, so this is by far the most common approach to Grails application deployment in production. Creating a WAR file is as simple as executing the war command:grails war
grails war /opt/java/tomcat-5.5.24/foobar.war
grails-app/conf/BuildConfig.groovy
that changes the default location and filename:grails.project.war.file = "foobar-prod.war"
grails.war.dependencies
in BuildConfig.groovy to either lists of Ant include patterns or closures containing AntBuilder syntax. Closures are invoked from within an Ant "copy" step, so only elements like "fileset" can be included, whereas each item in a pattern list is included. Any closure or pattern assigned to the latter property will be included in addition to grails.war.dependencies
.Be careful with these properties: if any of the libraries Grails depends on are missing, the application will almost certainly fail. Here is an example that includes a small subset of the standard Grails dependencies:def deps = [ "hibernate3.jar", "groovy-all-*.jar", "standard-${servletVersion}.jar", "jstl-${servletVersion}.jar", "oscache-*.jar", "commons-logging-*.jar", "sitemesh-*.jar", "spring-*.jar", "log4j-*.jar", "ognl-*.jar", "commons-*.jar", "xstream-1.2.1.jar", "xpp3_min-1.1.3.4.O.jar" ]grails.war.dependencies = { fileset(dir: "libs") { for (pattern in deps) { include(name: pattern) } } }
DEFAULT_DEPS
and DEFAULT_J5_DEPS
variables.The remaining two configuration options available to you are grails.war.copyToWebApp
and grails.war.resources
. The first of these lets you customise what files are included in the WAR file from the "web-app" directory. The second lets you do any extra processing you want before the WAR file is finally created.// This closure is passed the command line arguments used to start the // war process. grails.war.copyToWebApp = { args -> fileset(dir:"web-app") { include(name: "js/**") include(name: "css/**") include(name: "WEB-INF/**") } }// This closure is passed the location of the staging directory that // is zipped up to make the WAR file, and the command line arguments. // Here we override the standard web.xml with our own. grails.war.resources = { stagingDir, args -> copy(file: "grails-app/conf/custom-web.xml", tofile: "${stagingDir}/WEB-INF/web.xml") }