DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Java CI/CD: From Local Build to Jenkins Continuous Integration
  • Optimizing CI/CD Pipeline With Kubernetes, Jenkins, Docker, and Feature Flags
  • Jenkins in the Age of Kubernetes: Strengths, Weaknesses, and Its Future in CI/CD
  • Implementing CI/CD Pipelines With Jenkins and Docker

Trending

  • The Ultimate Guide to Code Formatting: Prettier vs ESLint vs Biome
  • How Large Tech Companies Architect Resilient Systems for Millions of Users
  • Navigating Double and Triple Extortion Tactics
  • Simplifying Multi-LLM Integration With KubeMQ
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. DevOps and CI/CD
  4. End-to-End Tutorial for Continuous Integration and Delivery by Dockerizing a Jenkins Pipeline

End-to-End Tutorial for Continuous Integration and Delivery by Dockerizing a Jenkins Pipeline

Learn how to implement container technologies with your Jenkins CI/CD workflows to make them easier to manage in this tutorial.

By 
Hüseyin Akdoğan user avatar
Hüseyin Akdoğan
DZone Core CORE ·
Nov. 30, 17 · Tutorial
Likes (15)
Comment
Save
Tweet
Share
32.3K Views

Join the DZone community and get the full member experience.

Join For Free

Continuous integration and continuous delivery are highly fundamental topics in the software industry, especially with cloud and container technologies. Container technologies such as Docker, Kubernetes, and OpenShift and automation servers like Jenkins make it easier to manage our project workflows.

The repository I have created answers the question of how to automatically manage the process of building, testing with the highest coverage, and deploying phases.

Our goal is to ensure our pipeline works well after each code being pushed. The processes we want to auto-manage:

  • Code checkout

  • Run tests

  • Compile the code

  • Run Sonarqube analysis on the code

  • Create Docker image

  • Push the image to Docker Hub

  • Pull and run the image

1) Running the Services

Since one of the goals is to obtain the Sonarqube report of our project, we should be able to access Sonarqube from the Jenkins service. Docker composeis the best choice to run services working together. We configure our application services in a yaml file, as below.

docker-compose.yml

version: '3.2'
services:
  sonarqube:
    build:
      context: sonarqube/
    ports:
      - 9000:9000
      - 9092:9092
    container_name: sonarqube
  jenkins:
    build:
      context: jenkins/
    privileged: true
    user: root
    ports:
      - 8080:8080
      - 50000:50000
    container_name: jenkins
    volumes:
      - /tmp/jenkins:/var/jenkins_home #Remember that, the tmp directory is designed to be wiped on system reboot.
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - sonarqube

The paths of Docker files of the containers are specified at context attribute in the docker-compose file. The content of these files as follows:

sonarqube/Dockerfile

FROM sonarqube:6.7-alpine

jenkins/Dockerfile

FROM jenkins:2.60.3

If we run the following command in the same directory as the docker-compose.yml file, the Sonarqube and Jenkins containers will spin up and run.

docker-compose -f docker-compose.yml up --build
docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED              STATUS              PORTS                                              NAMES
87105432d655        pipeline_jenkins     "/bin/tini -- /usr..."   About a minute ago   Up About a minute   0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp   jenkins
f5bed5ba3266        pipeline_sonarqube   "./bin/run.sh"           About a minute ago   Up About a minute   0.0.0.0:9000->9000/tcp, 0.0.0.0:9092->9092/tcp     sonarqube

GitHub Configuration

We’ll define a service on GitHub to call the Jenkins Github webhook because we want to trigger the pipeline. To do this, go to Settings -> Integrations & services. The Jenkins Github plugin should be shown on the list of available services, as below.

Image title

After this, we should add a new service by typing the URL of the dockerized Jenkins container along with the /github-webhook/ path.

Image title

The next step is to create an SSH key for a Jenkins user and define it as Deploy keys on our GitHub repository.

Image title

If everything goes well, the following connection request should return with a success.

ssh git@github.com
PTY allocation request failed on channel 0
Hi <your github username>/<repository name>! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

Jenkins Configuration

We have configured Jenkins in the docker compose file to run on port 8080 therefore if we visit http://localhost:8080 we will be greeted with a screen like this.

Image title

We need the admin password to proceed to installation. It’s stored in the /var/jenkins_home/secrets/initialAdminPassword directory and also it’s written as output on the console when Jenkins starts.

jenkins      | *************************************************************
jenkins      |
jenkins      | Jenkins initial setup is required. An admin user has been created and a password generated.
jenkins      | Please use the following password to proceed to installation:
jenkins      |
jenkins      | 45638c79cecd4f43962da2933980197e
jenkins      |
jenkins      | This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
jenkins      |
jenkins      | *************************************************************

To access the password from the container.

docker exec -it jenkins sh
/ $ cat /var/jenkins_home/secrets/initialAdminPassword

After entering the password, we will download recommended plugins and define anadmin user.

Image title

Image title

Image title

After clicking Save and Finish and Start using Jenkins buttons, we should be seeing the Jenkins homepage. One of the seven goals listed above is that we must have the ability to build an image in the Jenkins being dockerized. Take a look at the volume definitions of the Jenkins service in the compose file.

- /var/run/docker.sock:/var/run/docker.sock

The purpose is to communicate between the Docker Daemon and the Docker Client (we will install it on Jenkins) over the socket. Like the docker client, we also need Maven to compile the application. For the installation of these tools, we need to perform the Maven and Docker Client configurations under Manage Jenkins -> Global Tool Configuration menu.

Image title

We have added the Maven and Docker installers and have checked theInstall automatically checkbox. These tools are installed by Jenkins when our script (Jenkins file) first runs. We give myMaven and myDocker names to the tools. We will access these tools with this names in the script file.

Since we will perform some operations such as checkout codebase and pushing an image to Docker Hub, we need to define the Docker Hub Credentials. Keep in mind that if we are using a private repo, we must define Github credentials. These definitions are performed under Jenkins Home Page -> Credentials -> Global credentials (unrestricted) -> Add Credentials menu.

Image title

We use the value we entered in the ID field to Docker Login in the script file. Now, we define pipeline under Jenkins Home Page -> New Item menu.

Image title

In this step, we select GitHub hook trigger for GITScm pooling options for an automatic run of the pipeline by Github hookcall.

Image title

Also in the Pipeline section, we select the Pipeline script from SCM as Definition, define the GitHub repository and the branch name, and specify the script location (Jenkins file).

Image title

After that, when a push is done to the remote repository or when you manually trigger the pipeline by Build Now option, the steps described in the Jenkins file will be executed.

Image title

Reviewing Important Points of the Jenkins File

stage('Initialize'){
    def dockerHome = tool 'myDocker'
    def mavenHome  = tool 'myMaven'
    env.PATH = "${dockerHome}/bin:${mavenHome}/bin:${env.PATH}"
}

The Maven and Docker client tools we have defined in Jenkins under Global Tool Configuration menu are added to the PATH environment variable for using these tools with a sh command.

stage('Push to Docker Registry'){
    withCredentials([usernamePassword(credentialsId: 'dockerHubAccount', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
        pushToImage(CONTAINER_NAME, CONTAINER_TAG, USERNAME, PASSWORD)
    }
}

withCredentials provided by Jenkins Credentials Binding Plugin and bind credentials to variables. We passed dockerHubAccount value with credentialsId parameter. Remember that, dockerHubAccount value is Docker Hub credentials ID we have defined it under Jenkins Home Page -> Credentials -> Global credentials (unrestricted) -> Add Credentials menu. In this way, we access to the username and password information of the account for login.

Sonarqube Configuration

For Sonarqube, we have made the following definitions in the pom.xml file of the project.

<sonar.host.url>http://sonarqube:9000</sonar.host.url>
...
<dependencies>
...
    <dependency>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>sonar-maven-plugin</artifactId>
        <version>2.7.1</version>
        <type>maven-plugin</type>
    </dependency>
...
</dependencies>

In the docker compose file, we gave the name of the Sonarqube service which is sonarqube, this is why in the pom.xml file, the sonar URL was defined as http://sonarqube:9000.

In this article, I have tried to share an end-to-end tutorial, I hope this could help your needs.

Jenkins (software) Continuous Integration/Deployment Pipeline (software) Docker (software) Kubernetes Integration Delivery (commerce)

Published at DZone with permission of Hüseyin Akdoğan. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Java CI/CD: From Local Build to Jenkins Continuous Integration
  • Optimizing CI/CD Pipeline With Kubernetes, Jenkins, Docker, and Feature Flags
  • Jenkins in the Age of Kubernetes: Strengths, Weaknesses, and Its Future in CI/CD
  • Implementing CI/CD Pipelines With Jenkins and Docker

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!