Web application war files can quickly grow. Here are some of the options to deploy a war to production.
Simply copy the war from the build machine to the production machine then deploy it.
Pro – Simple.
Con – Slow if large war file and slow connection.
Build the war file on the production machine then deploy it.
Pro – Built in the exact production environment, use VCS for very small transfers and build triggers.
Con – Full SDK on production machine and enough server resources to not effect production application.
I actually used this for some time on a demo site and it worked well until resources became an issue.
The effect on the production application can be minimised with `renice +19 -p $$` and `ionice -c2 -n7 -p $$ ` in the build script. But once you run out of RAM and go into swap even this can’t help.
Rsync the war to the production machine then deploy it.
Pro – Faster than copy method and still simple.
Con – Don’t get the full performance of rsync since small changes in source cause larger changes in zip/war files.
This is my current favourite method, war files can be rsync pushed from build machine to a binary repository (e.g. maven) then production machines can rsync pull and deploy. Rsync is averaging a 4-5 speedup with 14/60MB or 25% transfer. It’s modular, recoverable and makes sense.
Commands – Standard mod-time and size comparison `rsync -avzh –progress $SRC $DEST` or for the more accurate checksum comparison `rsync -acvzh –progress $SRC $DEST`.
Rsync the exploded war to the production machine then zip and deploy or deploy exploded.
Pro – Transfer is very fast.
Con – Hidden complexity and war files are designed to be deployed not exploded first.
Initially this seems ideal but has complications.
Distributing war files then adding unzip/re-zip to the process adds failure and variation points.
The war can be unzipped on the build or repository server then rsynced to an existing exploded dir. The transfer is very fast but unzipping/re-zipping time cancels the benefit.
Commands – Grails can be set to leave the staging dir exploded and not build the war with `grails -Dgrails.war.exploded=true war`. This can be used in conjunction with `grails.project.war.exploded.dir = “target/exploded-war”`. Building the war can be accomplished with `zip -r myapp.war exploded-war` or `jar -cf myapp.war exploded-war/` or even an ant build task. But none of these provided a war file with the exact build size of `grails war` and the build is no longer atomic but partial and distributed. The war build can be skipped altogether but this defeats all the benefits of war files in the first place.