Skip to main content

Jenkins CI/CD Pipeline

This project uses a Jenkins declarative pipeline to automate the entire deployment process, from source code checkout to running the containerized application. The pipeline ensures consistent, repeatable deployments with automatic notifications.

Complete Jenkinsfile

pipeline { 
    agent any 
 
    stages { 
        stage('Checkout') { 
            steps { 
                git branch: 'main', url: 'https://github.com/mani-6666/Mini-Project.git'
            } 
        } 
 
        stage('Build Docker Image') { 
            steps { 
                script { 
                    sh 'docker build -t react-express-app .' 
                } 
            } 
        } 
 
        stage('Run Container') { 
            steps { 
                script { 
                    // Stop old container if running 
                    sh 'docker ps -q --filter "name=react-express-app" | grep -q . && docker stop react-express-app && docker rm react-express-app || true' 
                    // Start new container 
                    sh 'docker run -d -p 5000:5000 --name react-express-app react-express-app' 
                } 
            } 
        } 
    } 
 
    post { 
        success { 
            echo " Deployment completed successfully!" 
        } 
        failure { 
            echo " Build or deployment failed!" 
        } 
    } 
}

Pipeline Structure

Agent Configuration

agent any
What this does:
  • Tells Jenkins to run the pipeline on any available agent
  • For simple setups, this runs on the Jenkins master node
  • Can be configured to run on specific agents with Docker or Node.js capabilities

Pipeline Stages

1

Stage 1: Checkout

Clone the source code from GitHub.
stage('Checkout') { 
    steps { 
        git branch: 'main', url: 'https://github.com/mani-6666/Mini-Project.git'
    } 
}
What happens:
  • Jenkins clones the repository from GitHub
  • Checks out the main branch
  • Pulls the latest code including Dockerfile, docker-compose.yml, and application source
  • Creates a fresh workspace for the build
This stage runs on every pipeline execution, ensuring you always build from the latest code.
2

Stage 2: Build Docker Image

Build the Docker image using the multi-stage Dockerfile.
stage('Build Docker Image') { 
    steps { 
        script { 
            sh 'docker build -t react-express-app .' 
        } 
    } 
}
What happens:
  • Executes docker build in the workspace directory
  • Uses the multi-stage Dockerfile to build the image
  • Tags the resulting image as react-express-app
  • Runs all three stages:
    1. Frontend build (React compilation)
    2. Backend build (Express setup)
    3. Production assembly
Build output includes:
  • npm install for frontend dependencies
  • React production build
  • npm install for backend dependencies
  • Final image assembly
Docker layer caching speeds up subsequent builds. If dependencies haven’t changed, cached layers are reused.
3

Stage 3: Run Container

Stop any existing container and start a new one with the fresh image.
stage('Run Container') { 
    steps { 
        script { 
            // Stop old container if running 
            sh 'docker ps -q --filter "name=react-express-app" | grep -q . && docker stop react-express-app && docker rm react-express-app || true' 
            // Start new container 
            sh 'docker run -d -p 5000:5000 --name react-express-app react-express-app' 
        } 
    } 
}
Command breakdown:Stopping the old container:
docker ps -q --filter "name=react-express-app" | grep -q . && 
  docker stop react-express-app && 
  docker rm react-express-app || true
  • docker ps -q --filter "name=react-express-app" - Find container by name
  • grep -q . - Check if a container was found
  • docker stop react-express-app - Stop the running container
  • docker rm react-express-app - Remove the stopped container
  • || true - Don’t fail if no container exists (first deployment)
Starting the new container:
docker run -d -p 5000:5000 --name react-express-app react-express-app
  • -d - Run in detached mode (background)
  • -p 5000:5000 - Map port 5000 from container to host
  • --name react-express-app - Name the container
  • react-express-app - Use the image built in Stage 2
Zero-downtime deployment: This approach causes brief downtime (a few seconds) while the old container stops and the new one starts. For production zero-downtime deployments, consider blue-green deployment or rolling updates.

Post-Build Actions

The pipeline includes post-build notifications:
post { 
    success { 
        echo " Deployment completed successfully!" 
    } 
    failure { 
        echo " Build or deployment failed!" 
    } 
}
Success condition:
  • All stages completed without errors
  • Container is running and accessible at http://localhost:5000
  • Displays success message in Jenkins console
Failure condition:
  • Any stage failed (checkout, build, or deployment)
  • Displays failure message
  • Build is marked as failed in Jenkins
These can be extended to send Slack notifications, emails, or trigger other actions.

Setting Up Jenkins

1

Install Required Plugins

Ensure Jenkins has these plugins:
  • Git Plugin - For repository checkout
  • Docker Plugin - For Docker commands
  • Pipeline Plugin - For declarative pipeline syntax
2

Configure Docker Access

Jenkins needs permission to run Docker commands:
sudo usermod -aG docker jenkins
sudo systemctl restart jenkins
This adds the jenkins user to the docker group.
3

Create Pipeline Job

In Jenkins:
  1. Click “New Item”
  2. Enter job name: react-express-app-pipeline
  3. Select “Pipeline” project type
  4. Click “OK”
4

Configure Pipeline

In the job configuration:Option 1: Pipeline from SCM
  • Definition: Pipeline script from SCM
  • SCM: Git
  • Repository URL: https://github.com/mani-6666/Mini-Project.git
  • Branch: main
  • Script Path: Jenkinsfile
Option 2: Direct Script
  • Definition: Pipeline script
  • Paste the complete Jenkinsfile content

Running the Pipeline

1

Trigger Build

Click “Build Now” in the Jenkins job.
2

Monitor Progress

Watch the pipeline stages execute:
  • Checkout (blue)
  • Build Docker Image (blue)
  • Run Container (blue)
Green checkmarks indicate success.
3

View Console Output

Click on the build number, then “Console Output” to see:
  • Git clone logs
  • Docker build progress
  • Container startup messages
4

Verify Deployment

Visit http://localhost:5000 to confirm the application is running.

Pipeline Execution Flow

Webhook Integration (Optional)

Automate deployments on every Git push:
1

Configure GitHub Webhook

In GitHub repository settings:
  1. Go to Settings → Webhooks → Add webhook
  2. Payload URL: http://your-jenkins-url/github-webhook/
  3. Content type: application/json
  4. Trigger: “Just the push event”
2

Enable Build Trigger in Jenkins

In the Jenkins job configuration:
  • Check “GitHub hook trigger for GITScm polling”
  • Save the configuration
Now every push to the main branch automatically triggers the pipeline.

Troubleshooting

Build Fails at Docker Build Stage

Check:
  • Docker is installed and running on Jenkins agent
  • Jenkins user has Docker permissions
  • Dockerfile syntax is correct
View logs:
sudo journalctl -u jenkins -f

Container Fails to Start

Check:
  • Port 5000 is available (not used by another process)
  • Docker image built successfully
  • Application code has no runtime errors
Debug:
docker logs react-express-app

Permission Denied Errors

Solution:
sudo usermod -aG docker jenkins
sudo systemctl restart jenkins

Enhancing the Pipeline

Consider these improvements:

Automated Testing

Add a test stage before building:
stage('Test') {
    steps {
        sh 'npm test'
    }
}

Environment Variables

Use Jenkins credentials for sensitive data:
environment {
    API_KEY = credentials('api-key')
}

Slack Notifications

Send notifications to Slack channels on success/failure

Multi-Environment

Deploy to dev, staging, and production environments

Next Steps

Docker Build

Deep dive into the multi-stage Dockerfile

Docker Compose

Learn about container orchestration

Build docs developers (and LLMs) love