Skip to main content

Installing Hudson as a service on Redhat

Posted by johnsmart on October 8, 2008 at 2:48 AM PDT

Hudson is a great little Continuous Integration server. One of Kosuke's more recent innovations has been to add a feature that lets you install Hudson as a service on Windows. A very useful feature indeed, as previously this was a fairly non-trivial operation. But what if you're running Hudson on a Linux server?

Now there are a few ways to do this. One possibility for example is to install Tomcat as a service and then deploy Hudson onto this server. There is plenty of documentation on the internet about how to install Tomcat as a service on a linux machine. But what if you don't like Tomcat? What if your quite happy with Hudson's built in web server, and can't be bothered setting up Tomcat on your server? You can by all means set up Hudson as a service by itself, and it isn't hard to do. A few techniques are documented on the Hudson web site. I recently went through the process on a Redhat linux machine, which is a little different from the examples on the side. So, for the record, here is a short rundown on how I did it.

First of all, it's a good idea to have a dedicated hudson user. You can create one in the standard Unix fashion, as shown here:

#adduser -m -s /bin/bash hudson

Next, you need to download the hudson.war file and place in in an appropriate directory. I put mine in /usr/share/hudson.

#mkdir /usr/share/hudson
#cd /usr/share/hudson
#wget http://hudson.gotdns.com/latest/hudson.war
#chmod
755 /usr/share/hudson/hudson.war

You can create simple start and stop scripts for Hudson as shown below. The start script (which I place in /usr/local/bin/start-hudson.sh) looks like this:

#!/bin/bash
HUDSON_WAR=/usr/share/hudson/hudson.war
HUDSON_LOG=/home/hudson/hudson.log
JAVA=$JAVA_HOME/bin/java
nohup nice $JAVA -jar $HUDSON_WAR > $HUDSON_LOG 2>&1 &

The stop script (/usr/local/bin/stop-hudson.sh) is a fairly basic one, as shown here:

#!/bin/bash
kill `ps -ef | grep hudson.war | grep -v grep | awk '{ print $2 }'`

Next, to make your installation a little cleaner, you can write a simple init script to start and stop Hudson using these scripts. The following is a very basic example, which starts and stops Hudson, and runs Hudson as the 'hudson' user (running Hudson as root is not a good idea):

#! /bin/bash
#
# hudson Start/Stop the Hudson Continuous Integration server.
#
# chkconfig: 345 91 10
# description: Hudson is a Continuous Integration server. \
#              It monitors a source code repository and triggers builds \
#              when it detects any changes. See https://hudson.dev.java.net/ \
#              for more details.
# processname: hudson
# pidfile: /var/run/hudson.pid


# Source function library.
. /etc/rc.d/init.d/functions

# Get config.
. /etc/sysconfig/network

# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 0

startup=/usr/local/bin/start-hudson.sh
shutdown=/usr/local/bin/stop-hudson.sh
export JAVA_HOME=/usr/java/jdk1.6.0
HUDSON_USER=hudson

start(){
echo -n $"Starting Hudson service: "
su - $HUDSON_USER -c $startup
RETVAL=$?
echo
}

stop(){
action $"Stopping Hudson service: "
su - $HUDSON_USER -c $shutdown
RETVAL=$?
echo
}

status(){
numproc=`ps -ef | grep hudson.war | grep -v "grep hudson.war" | wc -l`
if [ $numproc -gt 0 ]; then
  echo "Hudson is running..."
  else
  echo "Hudson is stopped..."
fi
}

restart(){
  stop
  start
}


# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
exit 1
esac

exit 0

Place this script in the /etc/init.d directory (e.g. /etc/init.d/hudson), and make it executable.

#chmod a+x /etc/init.d/hudson 

Now you can start and stop Hudson in a familiar Unix fashion:

# /etc/init.d/hudson start
Starting Hudson service:
# /etc/init.d/hudson status
Hudson is running...
# /etc/init.d/hudson stop
Stopping Hudson service:                                   [  OK  ]
# /etc/init.d/hudson status
Hudson is stopped...

Finally, you can set this up to start and stop when the server reboots, by placing links in the appropriate run level directories. The easy way to do this is to use the chkconfig command, as shown here:

# chkconfig --add hudson

And now, you should be good to go!

"One of the best and most useful courses I have attended...Best development course I have been on in a very long time...A 'must' course for serious Java developers..." - Read what people are saying about the Java Power Tools Bootcamps.

Comments

A dedicated hudson user.

Hi, I was reading your article & being a limited knowledge in Unix, I just would like to know, the reason of having a separate "hudson" user (adduser -m -s /bin/bash hudson ). Is there any security issue is related, if we dont create a separate user rather than configure as "root" user? As I am working on an installer project for a in-house Java Server gateway, Shall I also create some new user say "gateway" to run as a different user? Will other user also be able to use the service? Thanks.

One reason you might prefer the built-in (Winstone) embedded server over something like Tomcat or JBoss is memory footprint . I haven't got hard, scientific figures, but running Hudson on Tomcat certainly requires (quite a bit) more memory than running Hudson by itself.

Why not just using your distributions tomcat/jetty/jboss or whatever other Java container support, and run the hudson war in it? It's much easier, and you end up with the same result.

There are more accurate (but slightly more complex) ways to accomplish that, especially wrt finding the PID of the java process. Have a look at how I implemented that in my hudson.init script for openSUSE: http://linux01.gwdg.de/~pbleser/files/rpm/hudson/hudson.init.in (same trick is applicable to other Linux distros too)