Spring Petclinic CI/CD Pipeline
This project demonstrates a CI/CD pipeline for the Spring Petclinic application using Jenkins, Maven, SonarQube, Nexus, and Tomcat. The pipeline automates building, testing, code analysis, artifact storage, and deployment using Jenkins Pipeline as Code.
Project Links
- GitHub Repository: click here
Architecture
The project utilizes a modular, scalable architecture with three dedicated Virtual Machines (VMs):
Components
- Jenkins VM:
- Orchestrates the entire CI/CD pipeline
- Runs build and test processes
- Hosts SonarQube (running as Docker container)
- Integrates with SonarQube and Nexus
- Nexus VM:
- Manages and stores build artifacts
- Provides artifact versioning and distribution
- Tomcat VM:
- Hosts the application server
- Receives and deploys the final WAR file
Technologies Stack
Category | Technology |
---|---|
CI/CD Platform | Jenkins |
Build System | Maven |
Code Analysis | SonarQube |
Artifact Repository | Nexus |
Application Server | Tomcat |
Testing Framework | JUnit |
Runtime | Java 17 |
Pipeline Stages
The CI/CD pipeline follows these key stages:
- Git Checkout: Clone repository from GitHub
- Compile: Compile project using Maven
- Test: Run unit tests
- SonarQube Analysis: Analyze code quality
- Build: Package application as WAR
- Deploy to Nexus: Store artifacts
- Copy to Tomcat: Transfer WAR to server
- Deploy WebApp: Activate application
Infrastructure Setup
Prerequisites
- Ubuntu/Debian-based system
- Docker and Docker Compose
- Java Development Kit 17
- Maven 3.8+
Jenkins Installation
- Update system packages:
sudo apt update
- Install Jenkins:
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins
Nexus Installation
- Download and install Nexus:
cd /opt
wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz
tar -zxvf latest-unix.tar.gz
rm latest-unix.tar.gz
sudo mv nexus-3.* nexus
- Create systemd service:
sudo nano /etc/systemd/system/nexus.service
- Add configuration for Nexus service:
[Unit]
Description=nexus service
After=network.target
[Service]
Type=forking
LimitNOFILE=65536
ExecStart=/opt/nexus/bin/nexus start
ExecStop=/opt/nexus/bin/nexus stop
Restart=on-abort
[Install]
WantedBy=multi-user.target
- Enable and start Nexus:
sudo systemctl enable nexus
sudo systemctl start nexus
- Get the default admin password:
cat /opt/nexus/sonatype-work/nexus3/admin.password
Tomcat Installation
- Download and install Tomcat:
# Download and install Tomcat 11
wget https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.2/bin/apache-tomcat-11.0.2.tar.gz
# Create service user
sudo useradd -r -m -U -d /opt/tomcat -s /bin/false tomcat
# Extract and configure
tar xzf apache-tomcat-11.0.2.tar.gz
sudo mv apache-tomcat-11.0.2/* /opt/tomcat/
# Set permissions
sudo chown -R tomcat: /opt/tomcat
- Configure Tomcat users (
/opt/tomcat/conf/tomcat-users.xml
):
<tomcat-users>
<role rolename="manager-gui" />
<user username="manager" password="password" roles="manager-gui" />
<role rolename="admin-gui" />
<user username="admin" password="password" roles="manager-gui,admin-gui" />
</tomcat-users>
- Create Tomcat service (
/etc/systemd/system/tomcat.service
):
[Unit]
Description=Apache Tomcat 11 Web Application Server
After=network.target
[Service]
Type=forking
User=tomcat
Group=tomcat
Environment="JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64"
Environment="CATALINA_HOME=/opt/tomcat"
Environment="CATALINA_BASE=/opt/tomcat"
Environment="CATALINA_PID=/opt/tomcat/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
[Install]
WantedBy=multi-user.target
- Start Tomcat service:
sudo systemctl daemon-reload
sudo systemctl start tomcat
sudo systemctl status tomcat
SonarQube Setup
Create docker-compose.yaml
:
services:
sonarqube:
image: sonarqube:lts-community
depends_on:
- sonar_db
environment:
SONAR_JDBC_URL: jdbc:postgresql://sonar_db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
ports:
- "9000:9000"
sonar_db:
image: postgres:17.2-alpine3.21
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
POSTGRES_DB: sonar
Configuration Steps
Maven Settings
Update ~/.m2/settings.xml
:
<server>
<id>deployment</id>
<username>username</username> <!-- Nexus username -->
<password>password</password> <!-- Nexus password -->
</server>
Project Configuration
Update the pom.xml
with your Nexus Repository information:
<distributionManagement>
<repository>
<id>deployment</id>
<name>Internal Releases</name>
<url>http://<your-tomcat-server-ip>:8081/repository/spring-petclinic-release/</url>
</repository>
<snapshotRepository>
<id>deployment</id>
<name>Internal Snapshot Releases</name>
<url>http://<your-tomcat-server-ip>:8081/repository/spring-petclinic-snap/</url>
</snapshotRepository>
</distributionManagement>
Nexus Repository Configuration
- Access Nexus web interface
- Create Release Repository:
- Type: maven2 (hosted)
- Name: spring-petclinic-release
- Version Policy: Release
- Create Snapshot Repository:
- Type: maven2 (hosted)
- Name: spring-petclinic-snap
- Version Policy: Snapshot
Jenkinsfile Environment Variables
Update the following in the Jenkinsfile:
REMOTE_USER
: Tomcat server usernameREMOTE_HOST
: Tomcat server hostnameREMOTE_PATH
: Temporary file transfer locationTOMCAT_PATH
: Tomcat webapps directory- SonarQube authentication token
Deployment Verification
Nexus Repository
After successful deployment to Nexus, you should see:
-
Release artifacts in the
spring-petclinic-release
repository: -
Snapshot artifacts in the
spring-petclinic-snap
repository:
Tomcat Deployment
The application deployment can be verified in two ways:
-
Through Tomcat Manager UI:
The
/spring-petclinic
application should be listed as “running” -
Accessing the Application:
The Spring PetClinic application interface should be accessible