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
- Prerequisites
- Adding the Deploy Stage
- Stopping & Removing the Existing Container
- Running the New Container
- Wrapping in a
script
Block - Conditional Execution with
when
- Verifying the Deployment
- 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
)
- SSH key (e.g.,
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 Name | Description |
---|---|
Build Docker Image | Build and tag your Docker image |
Trivy Vulnerability Scanner | Scan the image for vulnerabilities |
Push Docker Image | Push the image to your Docker registry |
Deploy - AWS EC2 | SSH 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 { /* ... */ }
}
Variable | Source |
---|---|
MONGO_URI | Hard-coded connection string |
MONGO_USERNAME | Jenkins credential mongo-db-username |
MONGO_PASSWORD | Jenkins credential mongo-db-password |
GIT_COMMIT | Jenkins 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
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
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
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.
Links and References
Happy Deploying!
Watch Video
Watch video content