This repository demonstrates a complete CI/CD pipeline setup using Jenkins, SonarQube, and Docker. The pipeline automates the process of building, analyzing code quality, and deploying a static website to a Docker Server that acts as a web server using Nginx. Since GitHub does not support webhooks with local networks, this setup uses three VPS servers: Jenkins, SonarQube, and Docker.
The goal of this project is to create an automated CI/CD pipeline that:
- Builds the application code.
- Analyzes the code for vulnerabilities and quality issues using SonarQube.
- Deploys the application to a Docker Server that serves the static website using Nginx.
This setup ensures efficient development workflows, improved code quality, and seamless deployment in a production-like environment.
This project follows these security best practices to protect sensitive information:
-
Environment Variables: All sensitive information such as API keys, tokens, and passwords are stored in environment variables, not in the code.
- Copy
.env.exampleto.envand add your actual credentials - The
.envfile is excluded from Git via.gitignore
- Copy
-
Jenkins Credentials: All sensitive information in Jenkins is stored using the Jenkins Credentials Manager.
- SonarQube tokens
- GitHub credentials
- Docker registry credentials
-
SonarQube Configuration:
- The
sonar-project.propertiesfile is excluded from Git to prevent accidental credential leaks - Use the
sonar-project.properties.templateas a reference to create your local configuration - In Jenkins, SonarQube credentials are injected at runtime using the Credentials Manager
- Never commit the actual SonarQube token to the repository
- The
-
No Hardcoded Secrets: The codebase does not contain any hardcoded secrets or credentials.
-
Proper .gitignore: A comprehensive
.gitignorefile prevents sensitive files from being committed to the repository. -
Secure Communication: All services communicate over HTTPS/SSL.
- Jenkins: Automates the CI/CD pipeline (hosted on a dedicated VPS).
- SonarQube: Analyzes code for vulnerabilities, bugs, and code smells (hosted on a dedicated VPS).
- Docker: Containerizes the application for consistent deployment across environments (hosted on a dedicated VPS).
- Nginx: Serves the static website efficiently on the Docker Server.
- GitHub: Hosts the source code and integrates with Jenkins for version control.
The CI/CD pipeline consists of the following stages:
-
Source Code Checkout:
- Jenkins pulls the latest code from the GitHub repository.
-
Code Analysis:
- Runs a static code analysis using SonarQube to detect vulnerabilities, bugs, and code smells.
-
Docker Build:
- Builds a Docker image for the application using the official Nginx image.
-
Deployment:
- Deploys the Docker container to the Docker Server, where Nginx serves the static website.
Before setting up the pipeline, ensure you have the following tools installed and configured:
-
Three VPS Servers:
- Jenkins Server: For running the CI/CD pipeline.
- SonarQube Server: For code quality analysis.
- Docker Server: For hosting the deployed application and serving it using Nginx.
-
GitHub Repository:
- Ensure your repository is properly set up and accessible by Jenkins.
-
Webhook Configuration:
- Configure a webhook in GitHub to notify the Jenkins server whenever changes are pushed.
-
Install Jenkins:
- Install Jenkins on your VPS:
sudo apt update sudo apt install openjdk-11-jdk -y curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.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-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null sudo apt update sudo apt install jenkins -y sudo systemctl start jenkins
- Install Jenkins on your VPS:
-
Install Plugins:
- Go to Manage Jenkins > Manage Plugins.
- Install the following plugins:
- Git Plugin
- Docker Plugin
- SonarQube Scanner Plugin
-
Configure SonarQube:
- Add your SonarQube server details and token in Manage Jenkins > Configure System.
-
Create a New Pipeline Job:
- Create a new pipeline job in Jenkins.
- Configure the job to pull code from your GitHub repository.
-
Set Up Webhook:
- In your GitHub repository, go to Settings > Webhooks > Add Webhook.
- Set the payload URL to your Jenkins server's IP address (e.g.,
http://<jenkins-vps-ip>:8080/github-webhook/).
-
Install SonarQube:
- Install SonarQube on your VPS:
sudo apt update sudo apt install openjdk-11-jdk -y wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.9.0.65466.zip unzip sonarqube-9.9.0.65466.zip -d /opt/ sudo useradd -r -m -U -d /opt/sonarqube -s /bin/bash sonarqube sudo chown -R sonarqube:sonarqube /opt/sonarqube sudo nano /opt/sonarqube/conf/sonar.properties
- Update the
sonar.web.hostproperty to your VPS IP:sonar.web.host=<sonarqube-vps-ip>
- Install SonarQube on your VPS:
-
Start SonarQube:
sudo systemctl start sonarqube
-
Generate Token:
- Access the SonarQube dashboard at
http://<sonarqube-vps-ip>:9000. - Generate a token and add it to Jenkins for authentication.
- Access the SonarQube dashboard at
-
Add SonarQube Configuration to Your Project:
- Create a
sonar-project.propertiesfile in the root of your project:sonar.projectKey=my-app sonar.sources=. sonar.host.url=http://<sonarqube-vps-ip>:9000 sonar.login=<your-sonarqube-token>
- Create a
-
Install Docker:
- Install Docker on your VPS:
sudo apt update sudo apt install docker.io -y sudo systemctl start docker sudo systemctl enable docker
- Install Docker on your VPS:
-
Create a Dockerfile:
- Add a
Dockerfileto your project to define the container image:# Use the official Nginx image FROM nginx:alpine # Copy static files to the default Nginx public folder COPY . /usr/share/nginx/html # Expose port 80 EXPOSE 80 # Start Nginx CMD ["nginx", "-g", "daemon off;"]
- Add a
-
Test Locally:
- Build and run the Docker image locally to ensure it works:
docker build -t static-website . docker run -d -p 80:80 static-website
- Build and run the Docker image locally to ensure it works:
-
Deploy to Docker Server:
- Push the Docker image to a container registry (optional) or directly deploy it to the Docker Server:
docker build -t static-website . docker run -d -p 80:80 static-website
- Push the Docker image to a container registry (optional) or directly deploy it to the Docker Server:
Create a Jenkinsfile in the root of your repository to define the pipeline stages:
pipeline {
agent any
environment {
DOCKER_IMAGE = 'static-website'
SONARQUBE_TOKEN = credentials('sonarqube-token')
}
stages {
stage('Checkout') {
steps {
git branch: 'main', url: 'https://github.com/username/<Repository>.git'
}
}
stage('SonarQube Analysis') {
steps {
echo 'Running SonarQube analysis...'
withSonarQubeEnv('SonarQube') {
sh 'sonar-scanner'
}
}
}
stage('Build Docker Image') {
steps {
echo 'Building Docker image...'
script {
docker.build(DOCKER_IMAGE)
}
}
}
stage('Deploy') {
steps {
echo 'Deploying application to Docker Server...'
script {
docker.image(DOCKER_IMAGE).run('-p 80:80')
}
}
}
}
}- Jenkins pulls the latest code from GitHub.
- The pipeline runs a static code analysis using SonarQube to detect vulnerabilities.
- If the code passes the analysis, Jenkins builds a Docker image using the official Nginx image.
- Finally, the Docker container is deployed to the Docker Server, where Nginx serves the static website on port 80.
Feel free to contribute to this project by opening issues or submitting pull requests. Any feedback or suggestions are welcome!
This project is licensed under the MIT License.
For questions or feedback, feel free to reach out:
- GitHub: @0x1Jar