AB
The first part of our Node.js CI/CD pipeline series, focusing on setting up a basic pipeline with Jenkins and Docker.
In this tutorial, we will learn how to set up a Continuous Integration and Continuous Deployment (CI/CD) pipeline for a Node.js application using Jenkins. We will build a basic pipeline that includes code checkout, dependency installation, security scanning, and deployment with Docker.
The sample code for this project is available at Clone Website GitHub Repository.
Before starting this project, make sure you have the following prerequisites:
Let’s start by setting up Jenkins on an EC2 instance:
sudo apt update -y
sudo apt install openjdk-11-jdk -y
java -version
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
Remember to open port 8080 in your security group to access Jenkins.
Access Jenkins in your browser using http://<your-ec2-ip>:8080
Retrieve the initial admin password:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Install the suggested plugins when prompted.
Create an admin user with your credentials.
You need to install the following plugins:
To install these plugins:
Configure the global tools by going to Manage Jenkins → Global Tool Configuration:
NodeJS: Add NodeJS → Name it as “node-18.16.0” → Install automatically → Select version 18.16.0
SonarQube Scanner: Add SonarQube Scanner → Name it as “sonarqube” → Install automatically
OWASP Dependency Check: Add OWASP Dependency Check → Name it as “DP” → Install automatically
Install Docker on the Jenkins server:
sudo apt-get update
sudo apt-get install docker.io -y
sudo systemctl start docker
sudo docker run hello-world
sudo systemctl enable docker
docker --version
sudo usermod -a -G docker jenkins
sudo usermod -a -G docker $(whoami)
newgrp docker
sudo systemctl restart jenkins
Install SonarQube using Docker:
docker run -d --name sonarqube -p 9000:9000 sonarqube:lts-community
Access SonarQube at http://<your-ec2-ip>:9000
with the default login credentials:
Generate a token for Jenkins integration:
Add the token to Jenkins:
Now, let’s create a Jenkins pipeline:
pipeline {
agent any
tools {
nodejs 'node-18.16.0'
}
stages {
stage('Git Checkout') {
steps {
git url: 'https://github.com/amodh-2002/Clone_Website.git', branch: 'main'
}
}
stage('Install Dependencies') {
steps {
sh 'npm install'
}
}
stage('OWASP Dependency Check') {
steps {
dependencyCheck additionalArgs: '--scan ./', odcInstallation: 'DP'
dependencyCheckPublisher pattern: '**/dependency-check-report.html', projectToken: 'dependency-check-report'
}
}
stage('Build Docker Image') {
steps {
script {
withDockerRegistry([credentialsId: 'docker-hub-credentials', toolName: 'docker']) {
sh 'docker build -t amodh-2002/clone_website:1.0.0 .'
sh 'docker push amodh-2002/clone_website:1.0.0'
}
}
}
}
stage('Deploy with Docker') {
steps {
script {
withDockerRegistry([credentialsId: 'docker-hub-credentials', toolName: 'docker']) {
sh 'docker stop nodejs-app || true'
sh 'docker rm nodejs-app || true'
sh 'docker run -d --name nodejs-app -p 80:80 amodh-2002/clone_website:1.0.0'
}
}
}
}
}
post {
success {
echo 'Pipeline completed successfully!'
}
failure {
echo 'Pipeline failed!'
}
}
}
Before running the pipeline, add Docker Hub credentials to Jenkins:
Let’s break down each stage of our pipeline:
This stage clones the Node.js application repository. The application is a simple website clone that we’ll be building and deploying.
This stage installs all the npm dependencies required by the application.
This stage runs a security scan on the application dependencies to identify any known vulnerabilities.
This stage builds a Docker image for the application and pushes it to Docker Hub.
This stage deploys the application by running a Docker container from the image we built.
Automated Testing: Add automated testing stages (unit tests, integration tests) to ensure code quality.
Caching: Implement caching strategies for npm dependencies to speed up builds.
Environment Variables: Use environment variables for sensitive information instead of hardcoding them.
Versioning: Implement proper versioning for your Docker images.
Rollback Strategy: Have a rollback strategy in case a deployment fails.
Monitoring: Add monitoring to your pipeline to get insights into build times and failures.
Node.js Version Compatibility: Ensure the Node.js version in Jenkins matches the one your application requires.
Docker Permission Issues: If you encounter permission issues with Docker, make sure the Jenkins user is added to the Docker group.
Network Issues: If the Docker image push fails, check your internet connection and Docker Hub credentials.
Resource Limitations: If the build fails due to resource limitations, consider upgrading your instance or optimizing your build process.
In this tutorial, we’ve set up a basic CI/CD pipeline for a Node.js application using Jenkins and Docker. We’ve covered how to:
This setup provides a solid foundation for automating the deployment of Node.js applications.
In the next part of this series, we’ll explore how to implement a similar pipeline using CircleCI, offering an alternative approach to CI/CD for Node.js applications.