continuous deployment with jenkins
I suggest the following procedure:
one single shell script (stored somewhere on the jenkins server) does everything. Basically, the script does scp of the build artifact and then connects to the server (ssh) and does all the necessary tasks to deploy (setup maintenance page, backup the current app, deploy the new app, ...).
On the jenkins server, there are at least 2 jobs:
- the first one simply does the build (using maven, or any other build script)
- the second job does the deploy : so this job only runs the shell script. (I suggest one deploy job for each target environment : testing, production, ...)
It does not require any "special" jenkins plugin to achieve this "one click deployment". It only requires that the jenkins user has ssh access to the target server.
EDIT
Here is a sample shell script to illustrate my post
#This script will copy the last artifact build by the job "MyApp" to test.myserver.com
#and remotely execute the deployment script.
#copy the war to the server
#(the job "MyApp" is using maven, that's why the war can be found at this location)
scp -i <HOME_DIR>/.ssh/id_dsa $HUDSON_HOME/jobs/MyApp_Build/workspace/myapp/target/myapp.war [email protected]:/tmp/
#connect to the server and execute the deployment script
ssh -i <HOME_DIR>/.ssh/id_dsa [email protected]
#The following is just an example of what a deployment script can be.
#of course you must adapt it to your needs and environment
"cd <TOMCAT_DIR>;
#first copy the current war to a backup directory (additionaly, I have a cron task deleting old undeployed apps)
cp -rf myapp-apps/myapp* undeployed/myapp-apps/;
#execute a script (stored on the server) to properly stop the app
sh bin/myapp.sh stop;
#delete current app
rm -rf myapp-apps/myapp;
rm -rf myapp-apps/myapp.war;
#copy the uploaded war in tomcat app directory
cp /tmp/myapp.war myapp-apps/;
#execute a script (stored on the server) to start the app
sh bin/myapp.sh start"
Ideally, you should be using something like Fabric or Capistrano for deployments, and call those scripts from Jenkins. I've used Capistrano extensively for both Ruby On Rails and Non-Ruby applications too. The biggest advantage I see are:
- The intelligence built in to rollback the deployment in case there are errors while deployments.
- Hooks it provides to run a set of scripts such as DB migration, service restarts etc.
- Manual rollback in case you need to.
Using SSH compromises security on your environment
and is quite hard to troubleshoot.
It is better to install a Jenkins-Slave on the remote machine
and run the tests there by executing a Job on the Slave.
The Slave is monitored by the Server, which saves you a lot of trouble
managing the connection.
You can trigger the remote Job at the end of a successful build
and pass it the artifact of that build.
(can also have the first Job store the artifacts on a shared drive
and pass the location of those artifacts to the next Job).
See here:
- Jenkins - Distributed builds
- Jenkins - Parameterized Trigger Plugin
- Jenkins - Copy Artifact Plugin