Linux Services
I have an Ubuntu Linux VM that runs Jenkins, and to make life simpler I wanted to set up Jenkins to run as a service. I also wanted it to start up automatically at boot time, as that’s the sole function of the VM it’s running on.
So, here are my notes on setting up Jenkins as a service on Ubuntu Linux, which includes a script to manage (start, stop, check, restart) the Jenkins process too.
On Ubuntu (and most othe rLinux versions) you can check the current services with the command “service –status-all” – this should give you a list of all services, and their current status. You can (as root) also do “service <name> start” (or stop or restart) for each one.
Jenkins as a Service
To create a new service for Jenkins, take a look at the existing scripts in /etc/init.d/ for some examples.
By convention there are three main methods a basic service implements, they are; start, stop and restart. About the most basic structure of a service script is therfore something like this:
#!/bin/bash start() { echo “Starting Service” # Do start things here. }stop() { echo “Stopping Service” # Do stop things here. }restart() { echo “Restarting Service…” stop start } case “$1″ in |
obviously you still need to implement the start and stop functions though 🙂
To see a far more detailed example, take a look at the file /etc/init.d/skeleton, which you could copy and update to suit your needs if you prefer.
I decided on something halfway between the very basic example above and the far more complex example in “skeleton”, and did something like this (saved as “/etc/init.d/jenkins”):
# Example Jenkins auto-start service script # # description: manages Jenkins as a service # processname: jenkins # pidfile: /var/run/jenkins.pid # author: www.DonaldSimpson.co.uk# The user and the home dir that Jenkins runs under jenkins=/usr/local/jenkins # Your startup and stop scripts (see below) startup=$jenkins/bin/startup.sh shutdwn=$jenkins/bin/shutdown.shstart_jenkins() { echo “Starting Jenkins services…” su – jenkins -c “sh $startup” } stop_jenkins() { status_jenkins() { case “$1” in |
Update that to suit then save and change the permissions to make it executable:
chmod +x /etc/init.d/jenkins |
then you can check (as root) that you can call the methods in the script:
service jenkins status
service jenkins stop service jenkins start |
These should all now run as the Jenkins user via sudo and say something when called, even if it is just “I can’t find the scripts you told me to call” 🙂
Jenkins Startup and Stop scripts
So, you now need to create the missing startup and shutdown scripts, in my example they were:
/usr/local/jenkins/bin/startup.sh |
and
/usr/local/jenkins/bin/shutdown.sh |
An example of the Jenkins start-up and management script I normally use is at the end of this post – the main idea though, is that it sets what you want to set then starts Jenkins via nohup and outputs to a log file
I have also added and included some basic tests to my scripts and some (very) rudimentary error handling/checking, but you shoudl get the idea and all you really need is this line (with the variables set correctly):
${NOHUP} ${JAVA} -jar ${JENKINS_WAR} -D${MARKER} –httpListenAddress=0.0.0.0 –httpPort=${HTTP_PORT} > ${LOG_FILE} & |
Note: I often run multiple instances of Jenkins, so I explicitly specify the HTTP_PORT, and I use the -D${MARKER} to allow me to safely and easily find the correct PID for each project.
The httpListenAddress can normally go unset, but it’s something I’ve had to set before on multi-home’d hosts.
The stop part of my Jenkins management script finds the correct PID like this (and you could use a filter for the correct -D${MARKER} if you want that too):
PID=`${LSOF} -w -n -i tcp:${HTTP_PORT} | ${GREP} -v COMMAND | ${AWK} {‘print $2’}` |
and simply kills it.
For some of my scripts I also filter for process ID’s that were started in the current directory by checking “pwdx” against the PID, but only where I’m sure the corresponding start-up process is correct/reliable.
So, tweak to your taste and that should be the Jenkins service created and working too now; for start|stop|restart you can create individual scripts or wrappers that call something like the one script below with parameters, or break the script in to separate files if you prefer.
Setting Jenkins to start at boot time
If you want to start Jenkins at boot time/startup automatically then you still need to do one more small step. There are many different ways to do this depending on personal preference, your requirements and your version of Linux, but on Ubuntu it can be done easily with:
update-rc.d jenkins defaults |
“update-rc.d” simply installs and removes System-V style init script links – read the man page for full details, but the same idea applies to most versions of Linux.
update-rc.d -f jenkins remove |
will undo this if you no longer want it.
An example Jenkins server/process management script
As an example, here is my script to manage Jenkins processes – it could use some improvements but the basic start, stop, restart and check should give you enough to sort out something that works and suits your needs.
Better formatted version available here: https://github.com/DonaldSimpson/scripts/blob/master/JenkinsProcessManager.sh
#! /bin/bash -p # www.donaldsimpson.co.uk # Script to start|stop|restart|check an instance of Jenkins # For each new instance, the PROJECT and HTTP_PORT need to be updated: export PROJECT=jenkins export HTTP_PORT=9000 EXIT_STRING=”” JENKINS_ROOT=/opt/apps/jenkins export JENKINS_HOME=${JENKINS_ROOT}/${PROJECT} JENKINS_WAR=${JENKINS_HOME}/jenkins.warWAIT_TIME=5 START_WAIT_TIME=15 JAVA_HOME=/usr PATH=$JAVA_HOME/bin:$PATH JAVA=${JAVA_HOME}/bin/java NOHUP=/usr/bin/nohup LOG_FILE=${JENKINS_HOME}/debug_${PROJECT}.log MARKER=”JenkinsProcFor_${PROJECT}”NC=/bin/nc WGET=/usr/bin/wget LSOF=/usr/bin/lsof AWK=/usr/bin/awk GREP=/bin/grep FUSER=/bin/fuser ################################################################################# ### Functions Start ############################################################# ################################################################################# cleanup(){ trap ” QUIT _error() { say(){ saybold(){ check_folders(){ check_files(){ check_port_closed(){ check_port_open(){ start_process(){ check_log(){ check_html(){ check_process(){ stop_proc(){ start(){ restart(){ ################################################################################# case “$1” in |
Hope that helps! Any constructive comments, requests or suggestions for improvement are very welcome 🙂
Cheers, and sorry about the indenting,
Don
Discover more from Don's Blog
Subscribe to get the latest posts sent to your email.
Please note that when specifying the httpPort there should be two dashes – WordPress is only showing one of them though.
Also, if you get an error like the below, you will need to specify a different Ajp13 port like so (with two dashes before it):
—ajp13Port=9000
and make sure that port number is free.
java.io.IOException: Failed to start a listener: winstone.ajp13.Ajp13Listener
at winstone.Launcher.spawnListener(Launcher.java:229)
at winstone.Launcher.(Launcher.java:182)
at winstone.Launcher.main(Launcher.java:384)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at Main._main(Main.java:273)
at Main.main(Main.java:98)
Caused by: java.io.IOException: Failed to listen on port 8009
at winstone.ajp13.Ajp13Listener.start(Ajp13Listener.java:89)
at winstone.Launcher.spawnListener(Launcher.java:220)
… 8 more
Caused by: java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:365)
at java.net.ServerSocket.bind(ServerSocket.java:319)
at java.net.ServerSocket.(ServerSocket.java:185)
at java.net.ServerSocket.(ServerSocket.java:141)
at winstone.ajp13.Ajp13Listener.start(Ajp13Listener.java:84)
… 9 more
Ach no! use /usr/share/wrapper/make-wrapper-init.sh