Stage Overview
The Jenkins pipeline consists of four sequential stages that automate the software delivery process:Stage Details
- Clone
- Build
- Test
- Deploy
Clone Stage
The Clone stage checks out the source code from the GitHub repository.Implementation
stage('Clone') {
steps {
echo 'Cloning the repository...'
git branch: 'main', url: 'https://github.com/mani-6666/Jenkins-Pipeline-for-CI-CD.git'
}
}
Configuration
The Git branch to clone. This pipeline uses the
main branch.The GitHub repository URL to clone from.
Process Flow
- Jenkins echoes a status message
- Git clone command executes
- Repository contents are checked out to Jenkins workspace
- Subsequent stages have access to the source code
Common Issues
Private Repository Access: If cloning a private repository, you must configure credentials:
git branch: 'main',
url: 'https://github.com/org/repo.git',
credentialsId: 'github-credentials-id'
For better performance with large repositories, use shallow clones:
checkout([
$class: 'GitSCM',
branches: [[name: '*/main']],
extensions: [[$class: 'CloneOption', depth: 1, noTags: false, shallow: true]],
userRemoteConfigs: [[url: 'https://github.com/your/repo.git']]
])
Build Stage
The Build stage creates a Docker image from the application source code using the Dockerfile.Implementation
stage('Build') {
steps {
echo 'Building Docker image...'
sh 'docker build -t $IMAGE_NAME:latest .'
echo 'Docker image built successfully!'
}
}
Docker Build Command
docker build -t $IMAGE_NAME:latest .
Tag the image as
nodejs-demo-app:latestBuild context (current directory containing Dockerfile)
Dockerfile Used
The build stage uses this Dockerfile from the repository:FROM node:18-alpine
# Set working directory
WORKDIR /app
# Copy files
COPY package*.json ./
RUN npm install
COPY . .
# Expose port
EXPOSE 3000
# Run app
CMD ["node", "index.js"]
Build Process
- Base Image: Pulls
node:18-alpine(lightweight Node.js image) - Working Directory: Sets
/appas the working directory - Dependencies: Copies package.json and runs
npm install - Application Code: Copies all source files
- Port Configuration: Exposes port 3000
- Startup Command: Defines
node index.jsas the entry point
Prerequisites
Docker Installation RequiredThe Jenkins agent must have:
- Docker installed and running
- Jenkins user added to the docker group
- Sufficient disk space for image layers
Best Practices
Multi-stage Builds: For production, consider using multi-stage builds to reduce image size:
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
Test Stage
The Test stage installs Node.js dependencies and executes the test suite.Implementation
stage('Test') {
steps {
echo 'Running tests...'
sh 'npm install'
sh 'npm test || echo "No tests defined or test failed, continuing..."'
}
}
Commands Executed
npm install
Process Flow
Test Execution Behavior
The
|| echo "..." fallback ensures the pipeline continues even if:- No tests are defined in package.json
- Tests fail during execution
Production Configuration
For production environments, enforce test success:stage('Test') {
steps {
echo 'Running tests...'
sh 'npm install'
sh 'npm test' // Fails pipeline if tests fail
}
}
Advanced Testing Options
- Code Coverage
- Parallel Tests
- Test Artifacts
stage('Test') {
steps {
sh 'npm install'
sh 'npm run test:coverage'
publishHTML([
reportDir: 'coverage',
reportFiles: 'index.html',
reportName: 'Coverage Report'
])
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
sh 'npm run test:unit'
}
}
stage('Integration Tests') {
steps {
sh 'npm run test:integration'
}
}
}
}
stage('Test') {
steps {
sh 'npm install'
sh 'npm test'
}
post {
always {
junit 'test-results/**/*.xml'
}
}
}
Common Issues
Dependency Installation FailuresIf
npm install fails, check:- Node.js version compatibility
- Network access to npm registry
- Proper package.json syntax
- File permissions in workspace
Deploy Stage
The Deploy stage runs the Docker container and exposes the application on port 80.Implementation
stage('Deploy') {
steps {
echo 'Deploying Docker container...'
sh 'docker run --name Jenkins -d -p 80:3000 $IMAGE_NAME:latest'
echo 'App deployed on port 80!'
}
}
Docker Run Command
docker run --name Jenkins -d -p 80:3000 nodejs-demo-app:latest
Command Parameters
Assigns the container name as “Jenkins” for easy identification
Runs the container in detached mode (background process)
Maps host port 80 to container port 3000
The Docker image to run (built in the Build stage)
Port Mapping
Host Port 80 → Container Port 3000
- Container Port 3000: The Node.js application listens on this port internally
- Host Port 80: External users access the application via this port
Users can access the deployed application at:
http://your-server-ip:80http://your-server-ip(port 80 is default for HTTP)
Deployment Verification
After deployment, verify the container is running:# Check container status
docker ps | grep Jenkins
# View container logs
docker logs Jenkins
# Test the application
curl http://localhost:80
Common Issues
Port Already in UseIf port 80 is already in use:
# Check what's using port 80
sudo lsof -i :80
# Use a different port
docker run --name Jenkins -d -p 8080:3000 $IMAGE_NAME:latest
Container Name ConflictIf a container named “Jenkins” already exists:
# Remove existing container
docker rm -f Jenkins
# Or use a different name
docker run --name Jenkins-v2 -d -p 80:3000 $IMAGE_NAME:latest
Production Deployment Options
- Health Checks
- Resource Limits
- Auto-Restart
- Environment Variables
sh '''docker run --name Jenkins -d \
-p 80:3000 \
--health-cmd="curl -f http://localhost:3000 || exit 1" \
--health-interval=30s \
--health-timeout=10s \
--health-retries=3 \
$IMAGE_NAME:latest'''
sh '''docker run --name Jenkins -d \
-p 80:3000 \
--memory="512m" \
--cpus="1.0" \
$IMAGE_NAME:latest'''
sh '''docker run --name Jenkins -d \
-p 80:3000 \
--restart=unless-stopped \
$IMAGE_NAME:latest'''
sh '''docker run --name Jenkins -d \
-p 80:3000 \
-e NODE_ENV=production \
-e PORT=3000 \
$IMAGE_NAME:latest'''
Stage Dependencies
Each stage depends on the successful completion of previous stages:Related Documentation
Complete Jenkinsfile
View the full Jenkinsfile with all stages
Deployment Details
Deep dive into Docker deployment process