Skip to content

Simple automation with Jenkins

You would like to set up a continuous delivery pipeline for an application packaged using Docker containers. But for this case your application is not a simple single container but a real multicontainer architecture.

What is Jenkins

Jenkins is a Java-based tool. It's open source, and it's designed as a CI/CD tool to help you with your continuous integration and continuous delivery needs. It helps you automate your code building and testing, and it can help you with deploying your code to an environment.

And if we look at the Jenkins entry in Wikipedia, it says it better than I could.

Jenkins is an open-source automation server. It helps automate the parts of software development related to building, testing, and deploying, facilitating continuous integration and continuous delivery. It is a server-based system that runs in servlet containers such as Apache Tomcat. More on Wikipedia

You can also automate the code build of a wide variety of code from a most of code repositories. You can also use (or create) plugins, they can change the way that Jenkins looks, and adds extra functionality.

You can notice Jenkins icon, it's an image of a a servant, this is to reflect how it can help you with your development tasks.

Using Jenkins, you can have a developer save code to a repository, and when that code changes, Jenkins can check for changes and build that code automatically. It can even auto-deploy the code automatically for you to an environment.

With Jenkins, you can have multiple servers set up in your environment. You can have a primary and you can have several secondary systems. And for instance, you can have the primary pull the code whenever there's a commit, and it can send that code to these secondary servers for builds and tests.

You can also have different versions of the same code sent to the different systems as required, and you can run the same testing cases with the same code on different environments, and this can save you time with your development tasks. More, you can add credentials to your Jenkins jobs with encryption. Jenkins also supports backups and has plugins that can be used for this purpose and many more, I think you get the point

Pipeline and Jobs

Here we will talk about what are Jobs and Pipeline in Jenkins? A job is simply any automated process in Jenkins. So jobs and pipelines, what's the difference? Pipelines are Jenkins jobs that are enabled by using the pipeline plugin and they are still Jenkins jobs just a particular type of job.

With the default install you'll find 6 types of jobs or projects in Jenkins as you can see below.

We will see this later do not worry.

Quickstart Jenkins

First you need to set up a Jenkins server. The easiest way is to use the following Docker Compose configuration like this :

version: '3.7'
services:
  jenkins:
    image: jenkinsci/blueocean:latest
    user: root  # to allow Jenkins to access Docker daemon
    ports:
      - "8080:8080"
    volumes:
      - jenkins-data:/var/jenkins_home
    restart: always

volumes:
  jenkins-data:  # named volume for Jenkins data

The volumes defined in the preceding Compose file act as persistent storage to avoid losing your build configurations and data every time you restart your Jenkins container. It is the responsibility of the owner to back up and maintain those folders outside Docker containers.

Just run the docker-compose file and you get a functional Jenkins server running on you localhost here : http://localhost:8080

You need to get the admin password first as the documentation said, you can do this quickly with this docker below. Skip the proxy part is not relevant for our work here.
docker exec <YOUR-CONTAINER-ID> cat /var/jenkins_home/secrets/initialAdminPassword

This was an easy task, but unfortunately not useful because you need to build an image that includes your application and also need to start containers using the newly built image to test your application. This is not possible in a standard Docker container.

To solve this, you can add two more lines to our docker-compose.yml file

version: '3.7'
services:
  jenkins:
    image: jenkinsci/blueocean:latest
    user: root  # to allow Jenkins to access Docker daemon
    ports:
      - "8080:8080"
    volumes:
      - jenkins-data:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock 
      - /usr/bin/docker:/usr/bin/docker
    restart: always

volumes:
  jenkins-data:  # named volume for Jenkins data

Two new volumes will mount the socket used for the communication between Docker client and server and add the Docker binary itself to act as a client. This way, you can run Docker commands inside the Jenkins container, and they will be executed on the host in parallel to the Jenkins container itself.

Now, when you have a functional Jenkins server, let's take a look of the GUI here :

First jobs

Now that we have our Jenkins server, let's build our first mini job : create and run a user test Job that saves its output in a file Named user_test.txt ๐Ÿค“

Not very sexy but it a first good exercice to discover jenkins jobs :

  1. Once logged in to Jenkins, click New Item in the left pane. In the Enter an item name field, type user_test
  2. From the list of available item types, make sure that Freestyle project is selected. Click OK.
  3. In the configuration for the project, scroll down to the Build section and click the Add build step drop-down arrow.
  4. From the drop-down menu, select Execute shell.
  5. In the Command text box, add the code containing the uname and whoami commands required to output the desired information to the requested file name:
    uname -a && whoami > user_test.txt
    
  6. Then click Save.
  7. In the user_test project, click Build Now in the left pane.
  8. Verify that the build completes in the Build History pane.
  9. Once completed, click Workspace in the project pane.
  10. Click the view link to the right of the user_test.txt file.
  11. Verify that the output in the file displays jenkins.
  12. Click the back button in the browser window.
  13. Click on the drop-down arrow next to the build in the Build History pane and click Console Output like this :

Building from Github

You have two option to link Jenkins and Github :

  1. Build from public repository (easy: you do not have to setup crendentials)
  2. Build from private repository (easy if you know how to dig into the dev settings of github ๐Ÿ˜‚) and set-up the git server installation inside jenkins live below :

Once you have choosen a methods you can create a new freestyle project and add your git inside the source code managment section here :

Once it is synchronize you can run a build and see in the output console ๐Ÿฅณ

Update the Jenkins Plugins

๐Ÿšง It is very important to often upgrade your jenkins plugings in order to not have error in your jobs and pipeline. ๐Ÿšง

  1. In the menu at the top-right of the window, click the bell icon.
  2. Scroll down to the UI update, and click Apply Migration.
  3. In the menu on the left, click Manage Jenkins.
  4. Scroll down to the warning at the bottom, and click Go to plugin manager.
  5. Check the top checkbox to select all available plugins and click Update.
  6. Once all the items have been marked for actions, scroll down and check the Restart Jenkins when installation is complete and no jobs are running checkbox.
  7. Once restarted, reconnect to Jenkins with the credentials provided.

Configure the Maven Installer

Maven is a popular open-source build tool developed by the Apache Group to build, publish, and deploy several projects at once for better project management. The tool provides allows developers to build and document the lifecycle framework.

Maven is written in Java and is used to build projects written in C#, Scala, Ruby, etc. Based on the Project Object Model (POM), this tool has made the lives of Java developers easier while developing reports, checks build and testing automation setups.

Maven primarily intends to provide developers with a comprehensive, reusable, easily maintainable model for projects and plugins or tools to interact with and operate with this model. More informations on this article

That's why we will be using Maven inside our jenkins server, below a quick installation guide :

  1. In the menu on the left, click Manage Jenkins.
  2. Scroll down and, under System Configuration, click Tools.
  3. Under Maven installations, click Add Maven.
  4. In the Name box, enter M3.
  5. Make sure Install automatically is checked. and click Save.

Configure builds to use Maven

You are to create a project named mavenproject. This should pull the code from the git repo (https://github.com/linuxacademy/content-cje-prebuild.git) and build the project. This should include the call to the binary that creates the index.jsp file:

bash
go build bin/makeindex 
N.B. The index.jsp file needs to be tracked for version control purposes.
  1. In the menu on the left, click New Item.
  2. In the Enter an item name field, enter mavenproject.
  3. Select Freestyle project and click OK.
  4. In the menu on the left, click Source Code Management.
  5. Under Source Code Management, select Git.
  6. Copy the git repository link from the instructions and enter it into the Repository URL box.
  7. Scroll down, and under Build Steps, click the Add build step dropdown and select the Invoke top-level Maven targets option.
  8. From the Maven Version dropdown, select M3.
  9. In the Goals field, enter clean package.
  10. Click the Add build step dropdown and select the Execute shell option.
  11. In the Command window, enter bin/makeindex.
  12. Scroll down, and under Post-build Actions, click the Add post-build action dropdown and select the Archive the artifacts option.
  13. Under Archive the artifacts, click the Advanced dropdown and check the Fingerprint all archived artifacts checkbox.
  14. In the Files to archive field, enter index.jsp and click Save.
  15. In the menu on the left, click Build Now.
  16. Refresh the window and click the View link next to index.jsp. Verify the contents of the index.jsp file.

Distributing a Build

Like other computer science master/slave system, other Jenkins computers can be configured as slave machines to relieve the burden on the master Jenkins server. Often big compagnies need several different environments to test their builds. In this case, using a slave to represent each of the required environments is almost a must.

A slave is a machine configured to offload construction projects from the master and once configured, this job allocation is pretty automatic. The project's setup determines the exact delegation behaviour; some projects may opt to "stick" to a certain machine during a build, whereas others may roam freely across slaves.

We will not go into this part in this tutorial here ๐Ÿ˜‡