Building & Deploying a Spring Boot App in Docker compose with CI/CD


This blog post will guide you through setting up a CI/CD pipeline for a Spring Boot banking application, streamlining the build, deployment, and integration process. Using Jenkins, Docker, and GitHub, we'll automate every step, ensuring efficient and reliable software delivery. You'll also discover how to utilize a multi-node Jenkins setup and shared libraries for seamless automatic deployments
Repository for this Project: https://github.com/Saiprasad-1727/Springboot-app-devops.git
Project Overview
This project involves creating a complete CI/CD pipeline that automates the deployment of a Spring Boot-based banking application. Here are the steps we will follow:
Create AWS EC2 Instances to host Jenkins and Docker.
Set up Jenkins to automate the CI/CD pipeline.
Containerize the Spring Boot application using Docker.
Use a multi-node Jenkins setup to deploy the application on a development server.
Create a Jenkinsfile for automated builds and deployment.
Steps to Implement the Project
To set up a Jenkins Master-slave architecture on AWS, we will create two EC2 instances(t2.medium). The Jenkins Master instance will manage Jenkins, while the Jenkins slave instance, will host and deploy the Spring boot application.
Step 1: Create Two AWS EC2 Instances
We'll start by setting up two separate instances: one for the Jenkins Master and one for the Jenkins Slave.
Log in to AWS:
Go to the AWS Console and log in.Launch an EC2 Instance (Jenkins Master):
Go to the EC2 Dashboard and click on Launch Instance.
Select the Ubuntu 24.04 LTS AMI.
Choose t2.medium for the Jenkins Master instance.
Configure Security Group:
SSH (port 22) for remote access.
HTTP (port 80) to access Jenkins through the browser.
Click Review and Launch.
Launch an EC2 Instance (Jenkins Agent):
Repeat the above steps, select t2.medium for the Jenkins Agent instance.
Use the same key pair as used for the Jenkins Master.
Step 2 : Connect to two EC2 instances and update
SSH into both instances using below command:
Update Each EC2 Instance
Ensure both instances are up to date by running:
ssh -i <your-key>.pem ubuntu@<your-ec2-public-ip>
sudo apt update && sudo apt upgrade -y
Step 3: Install Java on Both Instances
Jenkins requires Java, so install OpenJDK 17 on each instance:
sudo apt install openjdk-17-jre -y
java -version
Step 4: Install Jenkins (Only on Jenkins Master)
we are going to build and deploy the application on second server, so no need to install the jenkins server on machine 2
create a bash script with jenkins.sh and provide the executable permisssions to it
vi jenkins.sh
chmod +x jenkins.sh
---------------------------------------------------------------------------------------------
sudo apt-get install -y ca-certificates curl gnupg
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins -y
sudo systemctl enable jenkins
sudo systemctl start jenkins
sudo systemctl status jenkins
------------------------------------------------
execute with below command
./jenkins.sh
with the above script we are going to install the Jenkins server.
Step 5: Install Docker and Docker-compose on Both Instances
create a bash script with docker.sh and provide the executable permisssions to it
sudo apt install docker.io -y
sudo usermod -aG docker $USER
newgrp docker
sudo apt install docker-compose -y
docker --version
docker-compose --version
execute with below command
./docker.sh
Step 6: To access the Jenkins, enable the 8080 port for master instance
Edit the security group of your Jenkins Master instance:
Go to the EC2 Dashboard, select Security Groups, and choose the security group associated with your EC2 instance.
Click on Edit Inbound Rules and add a rule for Custom TCP Rule with port 8080.
Access Jenkins in a web browser using
http://<your-ec2-public-ip>:8080
.Access Jenkins Admin Password
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Use this password to complete the initial setup in Jenkins by following the on-screen instructions.
Step 7: Generate public and private key in Master instance to create a multimode jenkins setup
Generate a public and private key with ssh-keygen
ubuntu@ip-172-31-20-236:~$ ssh-keygen Generating public/private ed25519 key pair. Enter file in which to save the key (/home/ubuntu/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/ubuntu/.ssh/id_ed25519 Your public key has been saved in /home/ubuntu/.ssh/id_ed25519.pub The key fingerprint is: SHA256:m5jirdY5AXnZ10BS0/LIwyjHc8ZgCf6oyDpuDvK7kYU ubuntu@ip-172-31-20-236 The key's randomart image is: +--[ED25519 256]--+ | ...++. | | . +.o.. | | ..= * * | | .o +o* X o | | E .o.oS= . | | . + ..o o | |o = o.ooo | |++ o.o+ | |=+++o... | +----[SHA256]-----+ ubuntu@ip-172-31-20-236:~$ cd .ssh/ ubuntu@ip-172-31-20-236:~/.ssh$ ls authorized_keys id_ed25519 id_ed25519.pub ubuntu@ip-172-31-20-236:~/.ssh$ ls -la total 20 drwx------ 2 ubuntu ubuntu 4096 May 1 11:29 . drwxr-x--- 4 ubuntu ubuntu 4096 May 1 11:17 .. -rw------- 1 ubuntu ubuntu 389 May 1 07:11 authorized_keys -rw------- 1 ubuntu ubuntu 419 May 1 11:29 id_ed25519 -rw-r--r-- 1 ubuntu ubuntu 105 May 1 11:29 id_ed25519.pub ubuntu@ip-172-31-20-236:~/.ssh$
private key is used step 8
copy the content
.pub
id_ed25519.pub
and paste inauthorized_keys
in directory.ssh/
on machine2
Step 8: Creating a Development Server from Jenkins Agent Instance to Deploy Spring boot bank App
To add a new node in Jenkins:
Log in to Jenkins.
Go to Manage Jenkins > Manage Nodes and Clouds.
Click New Node:
Node name: Enter a name for the Jenkins Agent (e.g.,
machine2
).Choose Permanent Agent and click OK.
Configure Node Settings:
Make sure to create a directory named app on the agent machine
Remote root directory:
/home/ubuntu/app
Labels: Add
machine2
Usage: Choose Use this node as much as possible
Under Launch method, select Launch agents via SSH:
Host: Enter the PUBLIC IP of your Jenkins Agent instance.
Credentials: Add credentials by selecting SSH Username with private key.
Use ubuntu for the username.
Add the private key of master machine’s associated with the key pair used for the Jenkins Agent EC2 instance.
Click Save and connect to the Jenkins Agent.
Step 9: Set Up Docker Hub Credentials in Jenkins
Go to Manage Jenkins > Security > Credentials > System > Global credentials (unrestricted) and click Add Credentials.
Set Kind to Username with password.
Add your Docker Hub username and password and save , for password generate Personal Access Token on DockerHub.
Step 10: Create a Shared Library Repository
Create a GitHub Repository:
Go to GitHub and create a new repository.
Name it something like
Jenkins-shared-library
set it to Public or Private (based on your needs), and click Create Repository.
Clone the Repository:
Clone the repository to your local machine:
https://github.com/Saiprasad-1727/Jenkins-shared-library.git
and add the groovy scripts as follows which we are going to use in declarative pipeline
clone.groovy
Handles code cloning from a Git repository:
def call(String url, String branch){ git url:url , branch:branch }
dockerbuild.groovy
Builds a Docker image:
def call(String imageName, String imageTag){ sh "docker build -t ${imageName}:${imageTag} ." }
dockerpush.groovy
Pushes a Docker image to Docker Hub:
def call(String credId, String imageName,String imageTag){ withCredentials([usernamePassword(credentialsId:credId, usernameVariable:"dockerHubUser", passwordVariable:"dockerHubPass")]){ sh "docker login -u ${env.dockerHubUser} -p ${env.dockerHubPass}" sh "docker image tag ${imageName}:${imageTag} ${env.dockerHubUser}/${imageName}:${imageTag}" sh "docker push ${env.dockerHubUser}/${imageName}:${imageTag}" } }
deploy.groovy
Deploys a Docker container:
def call(){ sh "docker-compose down && docker-compose up -d" }
Step 11: Configure the Shared Library in Jenkins
Access Jenkins:
- Go to Manage Jenkins > Configure System.
Add Global Pipeline Library:
Scroll to Global Pipeline Libraries and click Add.
Fill in the details:
Name:
Shared
(matches@Library('Shared')
in yourJenkinsfile
).Default Version:
main
.Retrieval Method:
Modern SCM
.Source Code Management:
Select Git.
Add the repository URL:
https://github.com/Saiprasad-1727/Jenkins-shared-library.git
Add credentials if required (e.g., GitHub token or SSH key).
Save Configuration:
- Click Save.
Step 12: Create the jenkins pipeline for continious integration and deployment
jenkins > new item > Enter an item name as springboot-banking-app
> select pipeline
option and ok
write the description as per your wish
go to pipeline option on left side and start writing declarative pipeline for ci/cd as below
@Library('shared') _
pipeline {
agent { label 'machine2'}
stages{
stage("code"){
steps{
clone("https://github.com/Saiprasad-1727/Springboot-app-devops.git","main")
echo "code clonning done"
}
}
stage("build the images"){
steps{
dockerbuild("bankapp","latest")
echo "sucessfully build the image"
}
}
stage("push to cdockerhub"){
steps{
dockerpush("dockerHubCred","bankapp","latest")
echo "pushed sucessfully"
}
}
stage("deploying the application"){
steps{
deploy()
}
}
}
}
Click on Build Now and check the stage view, if any stage got error click on builds and the check the console output and verify the errors and try to correct the pipeline and any configuration.
outputs:
Conclusion
By following these steps, we have successfully set up a CI/CD pipeline to automate the deployment of your Springboot bank Application using Jenkins, GitHub, and Docker, shared libraries, multinode agent etc. This setup not only simplifies the deployment process but also enhances productivity.
Before you leave
If you enjoy the content I share, feel free to connect with me on Sai Prasad Annam there’s a lot more to explore, and I think you’ll find it intriguing!"
And feel free check out my devops projects publication Dashboard - Overview
Subscribe to my newsletter
Read articles from SAI PRASAD ANNAM directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

SAI PRASAD ANNAM
SAI PRASAD ANNAM
Hi there! I'm Sai Prasad Annam, an enthusiastic and aspiring DevOps engineer and Cloud engineer with a passion for integrating development and operations to create seamless, efficient, and automated workflows. I'm driven by the challenges of modern software development and am dedicated to continuous learning and improvement in the DevOps field.