← Back to Projects

End-to-End CI/CD — GitHub→ Jenkins→ Docker→ EC2

2025

Automated build pipeline with Docker image creation, GitHub webhook triggers, and zero-touch deployment to EC2 with Nginx reverse proxy.

Overview

Implemented industry-style CI/CD pipeline with automatic GitHub-to-Jenkins triggers via webhooks. Automated Docker image building, artifact management, and EC2 deployment with Nginx reverse proxy. Configured auto-restart policies and health checks for production-ready deployments.

Pipeline Flow

  1. 1Developer pushes code to GitHub repository
  2. 2GitHub webhook automatically triggers Jenkins pipeline
  3. 3Jenkins builds Docker image from repository Dockerfile
  4. 4Docker image tested and validated in Jenkins pipeline
  5. 5Jenkins SSHs into EC2 instance and pulls Docker image
  6. 6Container deployed with auto-restart and health checks
  7. 7Nginx reverse proxy routes traffic to containerized app

Technologies Used

GitHubJenkinsDockerEC2NginxLinuxShell Script

Key Skills Demonstrated

  • CI/CD pipeline design
  • GitHub webhooks
  • Docker image building
  • SSH deployments
  • Nginx configuration
  • Automation scripting

Architecture Diagram

🚀 CI/CD PIPELINE (Node.js + Jenkins + Docker + AWS)

                                         ┌─────────────┐
                                         │   Developer │
                                         └──────┬──────┘
                                                │
                                    Writes code • Git push
                                                │
                                                ▼
                                 ┌───────────────────────────┐
                                 │          GitHub           │
                                 └──────┬─────────┬──────────┘
                                        │         │
                                   Stores code    │
                                        │         │ Webhook triggers
                                        ▼         ▼
                                 ┌───────────────────────────┐
                                 │          Jenkins          │
                                 └──────┬────────────────────┘
                                        │
                         ┌──────────────┼────────────────────────────────┐
                         │              │                                │
                  Checkout code   Install deps/tests               Docker build
                         │              │                                │
                         ▼              ▼                                ▼
               Creates verified     Confirms code ok         Builds Docker image
                 code copy               │                Tags version + latest
                         │              │                                │
                         └──────────────┴────────────────────────────────┘
                                                │
                                                ▼
                                 ┌───────────────────────────┐
                                 │         DockerHub         │
                                 └──────┬────────────────────┘
                                        │
                                 Stores container image
                                        │
                                        ▼
                                 ┌───────────────────────────┐
                                 │     AWS EC2 Production    │
                                 └──────┬────────────────────┘
                                        │
                                Pull latest Docker image
                                        │
                                Stop old → Run new container
                                        │
                                        ▼
                                 ┌───────────────────────────┐
                                 │          Nginx            │
                                 └──────┬────────────────────┘
                                        │ Reverse proxy
                                        ▼
                              Users → http://server-ip
                                        │
                                        ▼
                                      App Live 🎉

Pipeline Flow

1

Code Push: Developer commits and pushes code to GitHub main branch

2

Webhook Trigger: GitHub webhook sends POST request to Jenkins with repository details

3

Jenkins Checkout: Jenkins clones the latest code from the repository

4

Build & Test: npm install runs, dependencies resolved, test suite executed

5

Docker Build: Dockerfile processed, multi-layer image created from Node.js base

6

Image Tag: Docker image tagged with build number and latest tag for version control

7

Registry Push: Docker image pushed to DockerHub with authentication credentials

8

SSH Deploy: Jenkins SSH connects to production server using pre-configured key pair

9

Container Deploy: Production server pulls latest image and stops/starts container

10

Auto-restart: Docker configured with restart policy unless-stopped for high availability

11

Nginx Routing: Nginx reverse proxy forwards external traffic to containerized app

12

Health Check: Pipeline validates deployment by hitting /health endpoint

Tools Used

Version Control

  • GitHub
  • Git
  • GitHub Webhooks

CI/CD Automation

  • Jenkins
  • Jenkins Pipeline (Groovy)
  • Jenkins Plugins (Git, Docker, SSH Agent)

Containerization

  • Docker
  • DockerHub
  • Dockerfile
  • Docker Compose

Infrastructure

  • AWS EC2
  • Ubuntu 22.04 LTS
  • Nginx
  • SSH

Application Runtime

  • Node.js
  • npm
  • Express.js

Automation Scripts

deploy.sh

Bash

Production deployment script: stops existing container, pulls latest image, starts new container with auto-restart policy

Jenkinsfile

Groovy

Pipeline as Code: defines all CI/CD stages (checkout, build, test, docker build, push, deploy, health check)

Dockerfile

Docker

Multi-stage Docker image building Node.js app from alpine base, installing dependencies, exposing port 3000

nginx.conf

Nginx

Nginx reverse proxy configuration: routes port 80 traffic to containerized app on port 3000, sets headers, enables WebSocket support

Deployments

Jenkins CI/CD Server

AWS EC2 t2.medium instance running Jenkins, Docker, Node.js for automated builds and deployments (Port 8080)

Production Application Server

AWS EC2 t2.micro instance running containerized Node.js app with Nginx reverse proxy (Port 80/443)

DockerHub Registry

Centralized Docker image repository storing all builds with version tags and latest tag for easy rollback

Challenges Faced & Solutions

⚠️ SSH Key Management Between Jenkins and Production Server

✓ Solution: Generated RSA 4096-bit key pair on Jenkins server, added public key to production server authorized_keys, configured Jenkins SSH Agent plugin with private key credentials, tested connectivity with StrictHostKeyChecking disabled

⚠️ Docker Permission Denied Errors

✓ Solution: Added jenkins and ubuntu users to docker group with sudo usermod -aG docker, applied changes with newgrp docker, removed need for sudo prefix on docker commands

⚠️ Container Port Conflicts During Redeployment

✓ Solution: Implemented container stop/removal in deploy.sh before starting new instance, used docker stop && docker rm to gracefully handle existing containers, added timeout handling

⚠️ Jenkins Server Resource Limitations

✓ Solution: Used EC2 t2.medium instance instead of t2.micro, allocated 4GB RAM and 2 vCPU to handle Jenkins + Docker operations, configured Docker image pruning in post-pipeline stage

⚠️ Nginx Reverse Proxy WebSocket Upgrade Headers

✓ Solution: Added proxy_set_header Upgrade $http_upgrade and Connection upgrade directives, configured proxy_cache_bypass $http_upgrade for proper WebSocket support

⚠️ GitHub Webhook Reliability in Testing

✓ Solution: Disabled SSL verification in webhook for testing environment (production would use verified HTTPS), implemented Jenkins endpoint validation, tested webhook delivery through GitHub UI

⚠️ DockerHub Authentication in Jenkins Pipeline

✓ Solution: Stored DockerHub credentials in Jenkins as Username + Password, used credentials() function in Jenkinsfile, piped password to docker login to avoid plaintext exposure

⚠️ Zero-Downtime Deployment Strategy

✓ Solution: Configured docker restart policy with unless-stopped, implemented 5-second delay after container start in deploy.sh, added health check endpoint validation before pipeline success

Metrics & Performance

Deployment Frequency

Every Git Push

Fully automated deployment triggered immediately on code push, enabling rapid iteration and continuous delivery

Pipeline Execution Time

2-3 minutes

End-to-end time from Git push to production deployment (checkout, build, docker build, push, deploy, health check)

Build Success Rate

100%

Consistent successful deployments with proper error handling and automatic rollback on health check failure

Deployment Downtime

< 30 seconds

Minimal downtime during container restart, users experience brief connection interruption during nginx reload

Container Uptime

99.9%

Docker restart policy unless-stopped ensures automatic recovery from container crashes or OOM situations

Code-to-Production Time

< 5 minutes

Complete latency from initial code commit to live serving in production with health verification

Infrastructure Cost

$20-30/month

Using AWS Free Tier for production (t2.micro) and minimal Jenkins server (t2.medium) with spot instances for cost optimization

About This Project

This project showcases practical DevOps skills including infrastructure provisioning, CI/CD automation, containerization, and orchestration. Each step is designed to demonstrate real-world scenarios that DevOps engineers face daily.