Certified Jenkins Engineer

Containerization and Deployment

Demo Deploy AWS EC2

In this guide, you’ll learn how to deploy a Dockerized Node.js application to an AWS EC2 instance using a Jenkins Pipeline. We’ll cover every step—from adding a deploy stage and managing Docker containers on EC2, to conditional execution and verifying your deployment.

Table of Contents

  1. Prerequisites
  2. Adding the Deploy Stage
  3. Stopping & Removing the Existing Container
  4. Running the New Container
  5. Wrapping in a script Block
  6. Conditional Execution with when
  7. Verifying the Deployment
  8. Links and References

Prerequisites

  • A Jenkins instance with the SSH Agent plugin installed
  • An AWS EC2 Ubuntu server accessible via SSH
  • A Dockerized application pushed to a Docker registry
  • Jenkins credentials configured for:
    • SSH key (e.g., aws-dev-deploy-ec2-instance)
    • MongoDB username & password (mongo-db-username, mongo-db-password)

1. Adding the Deploy Stage

After your Push Docker Image stage, insert a new stage called Deploy - AWS EC2. Here’s the skeleton of your declarative pipeline:

pipeline {
    agent any

    stages {
        stage('Build Docker Image') { /* ... */ }
        stage('Trivy Vulnerability Scanner') { /* ... */ }
        stage('Push Docker Image') { /* ... */ }
        stage('Deploy - AWS EC2') {
            steps { /* To be implemented */ }
        }
    }

    post {
        always { /* ... */ }
    }
}
Stage NameDescription
Build Docker ImageBuild and tag your Docker image
Trivy Vulnerability ScannerScan the image for vulnerabilities
Push Docker ImagePush the image to your Docker registry
Deploy - AWS EC2SSH into EC2 and restart the container

We’ll use the SSH Agent plugin to authenticate to EC2 using the private key credential aws-dev-deploy-ec2-instance.


2. Stopping & Removing the Existing Container

Use an SSH one-liner to detect if the solar-system container is running, then stop and remove it:

ssh -o StrictHostKeyChecking=no [email protected] "
if sudo docker ps -a | grep -q 'solar-system'; then
    echo 'Container found. Stopping...'
    sudo docker stop solar-system && sudo docker rm solar-system
    echo 'Container stopped and removed.'
fi
"

Note

Suppressing StrictHostKeyChecking avoids interactive host key prompts, which is essential for unattended CI/CD pipelines.


3. Running the New Container

Next, start a fresh container with your environment variables. These variables come from the global environment block in your Jenkinsfile:

ssh -o StrictHostKeyChecking=no [email protected] "
sudo docker run --name solar-system \
  -e MONGO_URI=$MONGO_URI \
  -e MONGO_USERNAME=$MONGO_USERNAME \
  -e MONGO_PASSWORD=$MONGO_PASSWORD \
  -p 3000:3000 \
  -d siddharth67/solar-system:$GIT_COMMIT
"

Define your environment variables at the top of the Jenkinsfile:

pipeline {
    agent any

    environment {
        MONGO_URI         = 'mongodb+srv://supercluster.d83jj.mongodb.net/superData'
        MONGO_USERNAME    = credentials('mongo-db-username')
        MONGO_PASSWORD    = credentials('mongo-db-password')
        SONAR_SCANNER_HOME = tool 'sonarqube-scanner-610'
    }

    stages { /* ... */ }
}
VariableSource
MONGO_URIHard-coded connection string
MONGO_USERNAMEJenkins credential mongo-db-username
MONGO_PASSWORDJenkins credential mongo-db-password
GIT_COMMITJenkins built-in variable

4. Wrapping in a script Block

Because we’re using conditional logic (if), wrap the SSH commands in a script step inside the declarative stage:

stage('Deploy - AWS EC2') {
    steps {
        script {
            sshagent(['aws-dev-deploy-ec2-instance']) {
                sh '''
                ssh -o StrictHostKeyChecking=no [email protected] "
                if sudo docker ps -a | grep -q 'solar-system'; then
                    echo 'Container found. Stopping...'
                    sudo docker stop solar-system && sudo docker rm solar-system
                    echo 'Container stopped and removed.'
                fi

                sudo docker run --name solar-system \
                  -e MONGO_URI=$MONGO_URI \
                  -e MONGO_USERNAME=$MONGO_USERNAME \
                  -e MONGO_PASSWORD=$MONGO_PASSWORD \
                  -p 3000:3000 -d siddharth67/solar-system:$GIT_COMMIT
                "
                '''
            }
        }
    }
    post {
        always { /* cleanup or notifications */ }
    }
}

5. Conditional Execution with when

Run the deploy stage only on feature branches by adding a when condition. You can also configure this filter in the Jenkins UI:

stage('Deploy - AWS EC2') {
    when {
        branch 'feature/*'
    }
    steps {
        script {
            sshagent(['aws-dev-deploy-ec2-instance']) {
                sh '''<same SSH block as above>'''
            }
        }
    }
}

Note

Using when { branch 'feature/*' } ensures that deployment only triggers for feature branches, preventing accidental prod deployments.


6. Verifying the Deployment

  1. Check Jenkins Console

    ssh -o StrictHostKeyChecking=no [email protected] "
    if sudo docker ps -a | grep -q 'solar-system'; then
        echo 'Container found. Stopping...'
        sudo docker stop solar-system && sudo docker rm solar-system
    fi
    "
    

    Sample logs:

    Warning: Permanently added '3.140.244.188' (ECDSA) to the list of known hosts.
    Container found. Stopping...
    Container stopped and removed.
    Unable to find image 'siddharth67/solar-system:5376ef9094c...' locally
    Status: Downloaded newer image for siddharth67/solar-system:5376ef9094c...
    cab883d639d9
    
  2. On the EC2 Instance

    sudo docker ps
    

    Expected output:

    CONTAINER ID   IMAGE                                        NAMES
    cab88363d990   siddharth67/solar-system:5376ef09...         solar-system
    
    COMMAND             CREATED          STATUS             PORTS
    "docker-entrypoint.s..." About a minute ago Up About a minute 0.0.0.0:3000->3000/tcp
    
  3. Access the Application
    Open a browser and navigate to:

    http://<EC2_PUBLIC_IP>:3000
    

Integration testing should follow to validate your application endpoints and data flow.


Happy Deploying!

Watch Video

Watch video content

Previous
Built in when conditions