02 Jul
Posted by suresk as Software Development, Websites, Groovy, Grails
I’ve been developing a bunch of small Grails apps lately, and I end up deploying them to my production box fairly frequently. This is kind of annoying because the upload speed on my home internet connection is terrible - it sometimes takes 7 or 8 minutes to upload a new WAR and during that time, my internet connection is unusable for anything else. I wanted a simple way to push new code to production without uploading a new WAR every time, and I know a few other people were looking for something similar, so here it is. It is pretty boring but it does the job. In my case, I deploy all of mine as ROOT.war, because they are always the default app for their domain. If yours is setup different, just replace ROOT.war with whatever your war should be named.
1. Check your code into Subversion (or CVS or whatever SCM of your choice - this guide assumes Subversion, however).
2. Add a build directory on your prod box (I have mine at /home/build/) - then check out individual projects under it (ie, /home/build/wiifit/).
3. In each project, add a property to application.properties for the deployment directory (ie - deploy.dir=/home/tc6/server/wiifit).
4. In grails, you can add groovy scripts to the /scripts/ directory, and then run them with grails
- Do a subversion checkout to get our latest changes.
- Build the war
- Copy it to our directory
This is what I came up with:
includeTargets << new File ( “${grailsHome}/scripts/War.groovy”)
target(‘default’: “Push a war to prod”) {
println “svn up”.execute().text
war()
Ant.copy(todir:Ant.antProject.properties.‘deploy.dir’, overwrite:true) {
fileset(dir:“.”, includes:“ROOT.war”)
}
}
Your script can have multiple targets. If you specify a ‘default’ one, like I have above, it is what will be run if you supply no target (which is what we want).
5. Now I have a simple shell script on my server to setup the environment variables and run the build.
export GROOVY_HOME=/usr/share/groovy
export GRAIILS_HOME=/usr/share/grails
export JAVA_HOME=/usr/java/jdk
export GWT_HOME=/usr/share/gwt
cd $1
$GRAILS_HOME/bin/grails -Dgrails.env=production prod-push ROOT.war
This script can then be re-used for all projects on the server.
6. To update our app, we simply do the following:
- Check our changes into Subversion
- SSH into our server and go to our /build/ directory
- Run the build script (ie, ./build.sh wiifit)
Our new app is live in less than a minute and we don’t kill our home internet connection :)
This solution may not be very good for high-usage, critical apps - if I were building (and leaving code) on a production app server at my day job, I’d be fired (and deserve it!) - but for small apps like I build, it is a good solution. This solution is pretty simple, but I’m working on a full deployment plugin for grails - fewer setup steps, tomcat management, etc.. If you have any suggestions or ideas, let me know.
2 Responses
Malek
July 2nd, 2008 at 8:44 am
1Good idea, I personally use a bash script for updating source code and redeploying my war in tomcat :
maybe you wish to check (and use) this project http://cargo.codehaus.org/Quick+start , since it seems to handle many containers in a standard way.
here’s my bash script :
#!/bin/bash
sudo /etc/init.d/tomcat stop
#just in case of pending process
sudo killall -u tomcat java
cd $MY_SVN_WORKING_COPY
svn update
grails prod war
sudo rm -R /usr/local/tomcat/webapps/$WEBAPP_NAME/
#optional
sudo rm -R /usr/local/tomcat/logs/*
sudo cp /usr/local/tomcat/webapps/$WEBAPP_NAME.war $ARCHIVE_DIR/webapps/$WEBAPP_NAME.war.old
sudo cp ./$WEBAPP_NAME-$(cat application.properties | grep “app.version” | awk ‘{split($0,a,”=”); split(a[2],b,”\r”); print b[1]}’).war /usr/local/tomcat/webapps/$WEBAPP_NAME.war
sudo chown tomcat:tomcat /usr/local/tomcat/webapps/$WEBAPP_NAME.war
sudo /etc/init.d/tomcat start
#End of script
Regards
suresk
July 2nd, 2008 at 8:56 pm
2Yes, I first used simple bash scripts as well. I started working on groovy scripts because it makes it more portable and using the groovy scripts becomes more useful as I do more with the deployment stuff.
I didn’t use Cargo because I have some big plans for my deployment plugin, and it didn’t look like I’d be able to cleanly leverage much of Cargo. Might be worth another look though.
RSS feed for comments on this post · TrackBack URI
Leave a reply
Categories
Archives
Links
Meta