CI/CD with Jenkins — Part 3: Use Jenkins for Continuous Delivery
In the previous tutorials of this three-part tutorial series, we looked at installing Jenkins on Ubuntu 16.04 and created a sample Java application with Maven. We also created a build job in Jenkins to build the sample web application and successfully executed our first build job.
In this last tutorial of the series, we will configure Jenkins for automating the build job. We will also look at the basics of continuous delivery by configuring Jenkins to automatically deliver our web application to a Tomcat web server.
Configuring Automatic Build
From your Jenkins dashboard, click on the sample job “MyMavenApp” to open the status page of the job. Now, click on the “Configure” link to open the configuration for the build job. Scroll down to find the “Build Triggers” section. You will see that the section has multiple options for the build triggers. For now, we are interested only in “Poll SCM” option. Select the checkbox and a text box to enter the polling schedule will appear. Schedule in Jenkins is set using slightly modified cron syntax.
The syntax of cron is as follows.
MINUTE HOUR DATE MONTH DAY
MINUTE - Minutes in an hour, (0 to 59)
HOUR - Hour of the day, (0 to 23)
DATE - Date of the month, (1 to 31)
MONTH - Month of the year, (1 to 12)
DAY - Day of the week, (0 to 7), 0 and 7 both are SundaysExamples.
0 20 * * * At 20:00 every day
0 4 * * 0 At 04:00 on every Sunday
0 22 * * 1-5 At 22:00 on every day-of-week from Monday through Friday
In the above screenshot, I have used H/5 which will poll for the changes in the source in every five minutes. In a production environment, you may want to poll the changes for a less frequent duration, such as in every 6 hours. You can use H /6 to achieve this. Once you have provided the cron schedule, save the configuration. You will see a new option has been added to the sidebar with the name “Git Polling Log”. You can use this option to learn about the last git polling.
To check, if Jenkins is triggering an auto build if there is some change in source code, we will make some change in the code. If everything is working than Jenkins should detect the change in next git poll. Once the change is detected, the automatic build should be started by Jenkins.
Log in to the terminal of your ECS instance using the sudo user. Switch to the directory where we have created the Maven sample project.
Edit the JSP file in the project and add some content. You can add a line to the body tag, writing I love Alibaba Cloud. The goal is just to make some changes in the file.
Once you have saved the file, add the updated files in git using the following command.
git add .
Now, commit the changes to the project.
git commit -m "Updated index.jsp"
You should see the following output.
aliyun@jenkins:~/MyMavenApp$ git add .
aliyun@jenkins:~/MyMavenApp$ git commit -m "Updated index.jsp"
[master 4e5e2ce] Updated index.jsp
1 file changed, 1 insertion(+)
Push the changes into the remote Github repository.
git push origin master
Once you have pushed the code into the remote repository, head back to Jenkins job and keep refreshing the web page. Since we have our Jenkins configured to poll for a change in SCM in every five minutes, it will not take much time for Jenkins to detect the change and start the build.
You can also check the information of build on build status page. You will see that the change has occurred on “index.jsp” and build is triggered by an SCM change.
Triggering Builds by a Script
You can also trigger a build by calling a special predefined URL through a web browser or from a script. This type of build trigger can be useful when we need to trigger the build from a script, or it can be used in source control system’s hook script. To enable the builds from an URL, go to the configuration page of the Maven Job we have created. Scroll down to find the “Build Triggers” section. Provide a random authentication token secret which will be used to authenticate the build triggers from the script. It is mandatory to supply this secret authentication token to trigger the build.
After saving the configuration, you can easily trigger the build by accessing the following URL.
For example, in my case, the build URL will be,
You can also add a comment or build cause by adding the parameter cause with the message. For example,
Below is the screenshot of the build invoked from URL tells you that build is started from a remote host with some IP address. It also shows the note attached while triggering the build.
Other Build Methods
There are few other build triggers supported by Jenkins which we can also be used trigger the builds.
Build after other projects are built: In this method, Jenkins triggers a build when some other project’s build is finished. For example, in the screenshot below, I have specified that “MyMavenApp” should be triggered as soon as another project named “SomeOtherProject” finishes its build and the build is stable.
Build periodically: Using this method, you can trigger a periodic build for your project. It does not matter if there is any change in source code or not. You will need to set the schedule of the trigger using cron syntax. To learn more about cron syntax, you can refer to the Poll SCM method describe above.
Continuous Delivery with Jenkins
Continuous Delivery is an approach in DevOps which aims at releasing the newer versions of software to the users automatically and more frequently.
To learn how to continuously deliver a new software version, we will use the same sample Maven project we have used while learning how to use Jenkins for continuous integration. In this section of the tutorial, we will configure Jenkins to automatically deploy the generated war file to Tomcat 8 web server. Tomcat 8 web server can be easily installed on Ubuntu 16.04 from the default Ubuntu repository. Once again, log in to your Ubuntu ECS instance as the sudo user and run the following command to install Tomcat 8 web server.
sudo apt -y install tomcat8 tomcat8-admin
By default, Apache Tomcat is configured to listen to the port “8080”. In our Ubuntu instance, we already have Jenkins listening to the port “8080”, thus we will need to change the Tomcat port. Open the Tomcat server configuration file.
sudo nano /etc/tomcat8/server.xml
Find the following lines.
<Connector port="8080" protocol="HTTP/1.1"
Change the value of port from “8080” to “8081”.
<Connector port="8081" protocol="HTTP/1.1"
Further, we will also need to create a new tomcat server user with “manager-script” role. This user will be used by Jenkins to configure the Tomcat server and to deploy the war application.
sudo nano /etc/tomcat8/tomcat-users.xml
Add the following line before in the text file.
<user username="jenkins" password="StrongPassword" roles="manager-script" />
Once done, the configuration should look like as follows.
Save the file and exit from the editor. You can now restart Tomcat server and enable it to automatically start at boot time by running the commands.
sudo systemctl restart tomcat8
sudo systemctl enable tomcat8
Our staging and testing environment for the web application is now ready. Further, we will need to configure Jenkins to automatically deploy the application into Tomcat 8. Log in to your Jenkins instance and navigate to “Manage Jenkins >> Manage Plugins”. Switch to “Available” tab and search for “Deploy to container” plugin.
Select the plugin and click “Install without restart” button. Go back to Jenkins dashboard and click on “MyMavenApp” project and open the project’s configuration page. Scroll down to find the “Post-build Action” and from the drop-down menu, select “Archive artifacts” option. Put the wildcard, */.war in “Files to archive” textbox. This will make Jenkins scan the whole workspace to find all the war files and archive it.
The archived artifacts will be available on every build information page to download. In future, you will be able to download the war files generated after every build.
Next, add another post-build action by selecting “Deploy war/ear to a container” from the drop-down menu. Put the wildcard, */.war in “WAR/EAR files” textbox to search for all war artifacts in the current workspace. In the “Context path” text input, provide the path on which your application will be published. For example, if you put “MyMavenApp” then the application will be deployed on the URL, “http://jenkins.example.com:8081/MyMavenApp". In the container, select “Tomcat 8.x” from the drop-down menu of “ Add container”.
Click on the “Add” button next to the “Credentials”. In “Add Credentials” interface, provide the username and password which we have entered in “tomcat-users.xml” file earlier. Leave the ID field blank for Jenkins to generate one. Provide a description of the key so that we can easily identify this credential later.
Once the key has been added, select it from the drop-down menu of “Credentials”. Provide the link to your Tomcat 8 instance along with the protocol “http” or “https” and the port on which tomcat is listening. The post-build step configuration should look like as shown in the screenshot.
Save the configuration and go back the main page of our sample project. Click on the link “Build now” to build the project. If you have followed the tutorial correctly, the build should be carried out successfully.
On the build information page, you will also be able to download the generated artifact. To check if Jenkins has successfully deployed the application on Tomcat 8, click on “Console Output”. Scroll down at the end and you will see the there are logs about Jenkins archiving the application and then deploying it on Tomcat 8.
Now, you can access your web application by browsing to “http://jenkins.example.com:8081/MyMavenApp". You should see that the application is successfully working. Since our application was a sample application, you should see nothing more than a just a “Hello World!” message.
In this last part of the tutorial, we have learned to configure the automatic builds in Jenkins using multiple methods. Finally, we enabled continuous delivery in Jenkins by configuring it to automatically deploy our sample web application in Tomcat 8 web server.
This concludes our three-part tutorial to get started with Jenkins. We have looked at the steps to install Jenkins automation server on a single node. We have also learned the basics of creating a CI/CD pipeline into Jenkins. While learning Jenkins, we also looked at the installation of Maven and creating a sample Java web application project in it. We looked at the basics of using “git” command such as initializing a project, creating a repository, committing changes, adding the remote origin and pushing changes into it. Similarly, you can set up your actual project into Jenkins. There are many approaches you can follow for a build pipeline. If you follow a similar configuration we used in this project, then you will just need to push a commit and Jenkins will do everything else for you. After pushing the changes, wait for the build to finish and you can find your application will be deployed in your container. Since we only covered the basics of Jenkin, you may go to the Jenkins documentation webpage.