Continuous Deployment via GitLab, Jenkins, Docker and Slack

Ahmet Atalay
Jan 29, 2017 · 7 min read

In this blog, we will do whole Continuous Deployment process step by step with following technologies: Spring Boot, GitLab, Jenkins,Docker and Slack. We will first create our sample spring boot app with its Unit & Integration tests, then will push it to the GitLab. After pushing the code, Jenkins pipeline will automatically receive code by web hook, and run the tests. If tests pass without any error, Jenkins will build the code and will deploy code to server via docker. Then finally it will send the docker image with its own snapshot to the docker hub registry. If any of the steps in pipeline fails, it will notify the user via Slack.

Before starting to continuous deployment process, let me show you to the below Continuous Deployment diagram that we will do in this blog.

In our scenario, we need Spring Boot app. You can clone sample spring boot app from my github repository: https://github.com/onedaywillcome1/ContinuousIntegrationAndContinuousDeliveryApp.git
It is Hello World Spring Boot-Maven app which owns 1 unit test & 1 integration test.
First, Make a setup in GitLab integrations menu to trigger Jenkins.

GitLab is now ready to trigger Jenkins when all setup is made in Jenkins.

Next, Let’s install Jenkins, Docker and some other requirements. Here is the final step of launched AWS EC2 instance. Instance public ip is: 52.11.94.229

Now let’s ssh to instance and install following requirements:

# ssh to instance
ssh -i ~/.ssh/jenkinskeypair.pem ec2-user@52.11.194.229

Jenkins is now up and running. You can access via http://52.11.194.229:8080 copy the Jenkins admin password as shown below and unlock jenkins and install suggessted plugins

Install GitLab & Slack plugin in Jenkins

Go to http://52.11.194.229:8080/pluginManager/available and select Gitlab plugin and install without restart.(In your case, public ip will change, don’t forget it)

After installing slack & gitlab plugin, we can do following step ( optional). Slack plugin needs outgoing webhook config. If we leave it blank, jenkins will give an exception. So, to fix this problem, we should do below steps:

sudo mkdir /var/lib/jenkins/init.groovy.d
sudo vi /var/lib/jenkins/init.groovy.d/disable-slack-webhooks.groovy

The copy below groovy script in disable-slack-webhooks.groovy file

import jenkins.model.Jenkins
import hudson.model.RootAction

Give Jenkins ownership to init.groovy.d directory and restart jenkins again:

sudo chown jenkins:jenkins -R /var/lib/jenkins/init.groovy.d
sudo service jenkins restart

Let’s configure jenkins now:

Go to http://52.11.194.229:8080/configure and Configure Java_home and M2_HOME as environment variables and fill the Slack notification settings.

Go to http://52.11.194.229:8080/configureTools and configure the M2 path

Now we have configured fully up and running Jenkins machine. Now, we can create our Pipeline job and create Pipeline script. Select “Build when a change is pushed to GitLab” button because we will push our code to Gitlab, and Gitlab will trigger

Copy below pipeline script to Pipeline job. In preparation stage, Jenkins will clone sample spring boot app from GitLab repository and will run tests in “Test” stage. If tests pass, it will switch to “Build” stage, then results and finally deployment stages.

node {
def mvnHome
stage(‘Preparation’) { // for display purposes
git ‘git@gitlab.com:<myRepo>/ContinuousIntegrationAndContinuousDeliveryApp.git'
mvnHome = tool 'M2'
}
stage('Test') {
try {
sh "'${mvnHome}/bin/mvn' test"
} catch (e) {
notifyStarted("Tests Failed in Jenkins!")
throw e
}
}
stage('Build') {
try {
sh "'${mvnHome}/bin/mvn' clean package -DskipTests"
}catch (e) {
notifyStarted("Build Failed in Jenkins!")
throw e
}
}
stage('Results') {
try{
archive 'target/*.jar'
}catch (e) {
notifyStarted("Packaging Failed in Jenkins!")
throw e
}
}
}
stage('Deployment') {
try{
sh '/var/lib/jenkins/workspace/Pipeline/runDeployment.sh'
}catch (e) {
notifyStarted("Deployment Failed in Jenkins!")
throw e
}
}
notifyStarted("All is well! Your code is tested,built,and deployed.")
}

Now go to /var/lib/jenkins/workspace/Pipeline directory. Create runDeployment.sh and deployment directories and put Dockerfile in deployment directory.

cd  /var/lib/jenkins/workspace/Pipeline
mkdir deployment

Finally, all is done! When you now push code to GitLab. GitLab will trigger Jenkins, then Jenkins will first run the tests, build, deploy in server and will send snapshot to Docker Registry, besides that it will notifies you when anything happens in pipeline via Slack

Our Spring app is now up and running:

And Docker images with its own snapshot sent to Docker hub registry:

Of course, my post which explains CD is not real-world example. In real-world example, there will be more features and security. But, it can be beneficial for developers who is new and try to understand Continuous Deployment flow. Please like the post, if you find it useful. ;) See you in next post!