continuous deployment with jenkins - jenkins

I want to deploy with jenkins to the test environment and to the production environment. To do so I need to connect to the server of the wanted environment, something like ssh/scp.
I would like to know what the best way is.
I found some plugins to do this, like the Jenkins-Deploy-Plug-in or Jenkins Publish over SSH Plugin. The first has lots of issues, which is not really trustworthy to deploy to production and for the second you need to change the global configuration, which is manual work for every deploy.
Any ideas how to solve this? Maybe with some scripts or plugins?
The only current idea I have is: to connect with jenkins to a server (maybe with the SSH Plugin) and to execute there a script that connects to the wished environment. But that are two connections. Is that really neccessary? I hope for a more straightforward way for this.
thanks for any hint.

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 deployeruser#test.myserver.com:/tmp/
#connect to the server and execute the deployment script
ssh -i <HOME_DIR>/.ssh/id_dsa deployeruser#test.myserver.com
#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"

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

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.

Related

Copy files from Bitbucket via Jenkins to a production server

I have got my code files in bitbucket and have configured a jenkins build job to run where there is a change in the bitbucket repository. At the end of which it has to copy the files from the repo to a directory located at a production server from where the application is running.
Is there a away to copy the files from repo to a server using a script inputed to jenkins?
I asume you have the files in the workspace of the job. How about copying the files via the command line? If you want to do so, insert a batch block for windows nodes or a shell block for linux nodes and use
cp original_file new_file
You have 2 possibilites:
Run a slave on the production server
In this case you run a slave on the production server, which connects to your master jenkins. The slave has to be run under a user, which is able to write the directory, where you want to copy the files too.
2 Variations of this possibility:
You can execute the clone (checkout) of the bitbucket repository on the master and then use stash to make the files accessible on the slave, running on the production server (https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#stash-stash-some-files-to-be-used-later-in-the-build).
You run the whole pipeline on the slave, which is running on the production server, which means the production server needs access to bitbucket.
There are several possibilities to connect a slave to a master: https://wiki.jenkins.io/display/JENKINS/Distributed+builds#Distributedbuilds-Differentwaysofstartingagents
Use remote copy possibilites
You copy the files with eg. scp in linux.
This has some security implications:
You have to add the password of the production to the jenkins credential store and pass it to the copy command
if using keys (recommended). You have to add the private key to the jenkins credential store and pass it to the command.

Deploy web app via Jenkins

I have recently started to mess about with Jenkins and am unsure how to deploy my web app to a basic server. I've gotten into the Pipeline (https://jenkins.io/doc/book/pipeline/) and it seems like a fantastic way to work.
Where I'm a bit stuck is in two spots:
Once my repo is in my workspace within Jenkins, how do I prep it so I am only deploying the files necessary for the application? For example, I don't need my src/ directory or my Vagrantfile when I'm deploying things.
How do I deploy my app to the server? I see examples all over the place, but I am getting a bit lost since there seems to be so many ways to do this. I'm assuming scp or something like that...?
To build off of #2, is there a way to deploy web apps as transactions (in one shot) rather than file-by-file?
Please let me know if I can provide any information for potential answers!
I can't speak to your specific use case but a common way to do this is the build-and-deploy model, where you will have 2 Jenkins jobs. The "build" job will check out from source, run build commands such as maven or make, and lastly will "archive" the build artifacts. The latter is an option under the 'post-build actions' tab at the bottom.
In the "deploy" job, you will grab the artifacts of your choice. You can fetch a single file, all of them, and everything in between. This requires use of the 'Copy Artifact' plug-in and it allows you to copy files generated by other jobs. Now you can run your usual deploy script in the 'Execute Command' box. Most command line paradigms are supported out of the box such as setting environment variables.
The instructions above assume that you want to run your application off of a host that you've provisioned as a Jenkins slave.
Use artifacts as mentioned by Paul Back, or a 3rd party artifactory server as in video
This is always tricky and error-prone. Why not spin up a fresh server with new release (humanly verified once)
Jenkins & Ansible is the answer here. This is how I deploy to production, since I am in no need to use anything like Docker (too many issues with particular app) so have to run the app natively. Quick example would be
You monitor a specific branch in gitlab / github or whatever else and then call a webhook on push / merge etc on that branch, at this point you deal with anything you need to do by running a playbook on the jenkins job that monitors that branch (jenkins).
in my case jenkins and ansible run on the same server. Jenkins runs the ansible playbook that does whatever I need to do.
for example with ansible, I copy certain files that need to be there, run configs / change filenames etc. setup nginx, run composer,
you get the point.

Jenkins- How do i run a batch command on Master in a job that runs on a slave

I'm trying to a run a simple windows batch command (say copy) on Master inside a job that's set to run on a particular slave.
What i'm trying to accomplish with this is that copy the build log that gets saved on a master to a shared drive that's accessible from master. Please advise.
You are going to have to make the jenkins file system visible on the client independently of Jenkins. Since you have a Windows client, you are probably going to have to setup sharing from the Jenkins master using samba or something of the sort.
What I do instead: When I need assets from master is I use curl or wget to download the assets to the clients. You can use the FSTrigger plugin to start builds when the file changes on the Jenkins master. Once curl or wget has run, your asset is then in the %WORKSPACE% directory and you can proceed.
I would recommend to handle the logfile copying (and maybe further tasks) as a dedicated job (let's call it "SaveLog"). SaveLog should be tied to run only on master.
You should then configure SaveLog to be triggered after completion of your primary job.
The Logfile is already available on master, even if you do not save any artifacts.
Should you need further files from the slave workspace, then you should save them as artifacts. SaveLog (on master) can then still decide whether to do anything useful with those artifacts.

Execute Shell script from workspace on remote machine after build successful (Jenkins)

The scenario is - I have a job A which runs my ant script and packages the artifact's for me.
I am also using parametrized Triggered plug in to Trigger my "Job B" which will deploy my artifact on remote machine.
The job A is working fine and also Job B.
The tasks that i have to perform with Job B are
GIT checkout (which contains my deployment scripts) (successfully doning).
Copying artifacts from previous build to Remote machine. (successfully doing)
Run shell script on remote machine(script present in workspace folder )- Facing issues.
I browsed various plug ins for the same but no one is allowing me to run shell script after , "SCP to remote machine" which is present in Post build action.
I would like to execute the same sequence, however if you guys have any other suggestions please share.
Thanks in Advance.!
As part of Publish Over SSH Plugin, you can execute a script after the files had been copied over.
Under Post-build Actions
Add Send build artifacts over SSH
Select a preconfigured server (done in global configuration)
Select files to copy from workspace
Enter Exec command
If one of the files you copy is your shell script, you can enter it here as an "exec command"
To solve my query i used Jenkins SSH Plugin. This provides a configuration tab where i can add multiple hosts and after that used them in my job level configuration.
Link to Plugin
you get privilege to execute shell script on remote host as pre-build step or post build step.
updated the path of publish over ssh it worked for me

Jenkins- Create Jobs on different servers

I want to configure Jenkins to build my code on 1 server. Then want to deploy it on another server using Jenkins.Both servers are using Linux I want to automate the entire process as much as possible. I went through some of plugins like pipeline, Job Import Plugin, etc
Can anyone guide me how to go about it ? Which plugins will be useful ? Any example or tutorial somewhere will be useful. The configuration of build pipeline plugin on jenkins was not seamless for me.
Thanks,
Bhargav
I would work it this way :
Install jenkins on your first server
Install the following plugins : ssh credentials, ssh slaves, copy to
slave, and restart jenkins
Go to Manage jenkins -> Manage credentials, and add ssh credentials
for your second server
Go to Manage jenkins -> Manage nodes, and create a passive slave.
The launch method should be "Launch slave agents on Unix machines
via ssh". You should use the credentials that you have added in step
3
Create a job to build your code. In the advanded options of job, you
should indicate that the job must only be built on master node.
Create a job to deploy your code on the second server. In the
avanded options of job, you should indicate that the job must only
be built on slave node.
In the "Build Environment" section, check the "Copy files into workspace before building" box and configure what files you want to copy from first server (https://wiki.jenkins-ci.org/display/JENKINS/Copy+To+Slave+Plugin)
The code will be copied into the jenkins slave's workspace.

Resources