Skip to content

Latest commit

Β 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ DevOps AWS - Express.js + Docker CI/CD Deployment

A production-ready Express.js TypeScript application with automated CI/CD deployment to AWS EC2 using GitHub Actions and Docker Hub.

Deployed Application

πŸ“‹ Table of Contents

🎯 Overview

This project demonstrates a complete DevOps workflow for deploying a Node.js/Express.js application to AWS EC2. It includes:

  • Automated Docker image building and pushing to Docker Hub
  • GitHub Actions CI/CD pipeline
  • Zero-downtime deployments with health checks
  • Nginx reverse proxy configuration
  • Production-ready Docker setup

✨ Features

  • Automated CI/CD: Push to main branch triggers automatic deployment
  • Docker Containerization: Application runs in isolated Docker containers
  • Zero Downtime: Health checks ensure smooth deployments
  • Security: SSH-based deployment with secrets management
  • Monitoring: Health check endpoint for application status
  • Scalability: Easy to scale with Docker Compose

πŸ› οΈ Tech Stack

  • Runtime: Node.js 20 (LTS)
  • Framework: Express.js 5
  • Language: TypeScript
  • Containerization: Docker & Docker Compose
  • CI/CD: GitHub Actions
  • Cloud: AWS EC2
  • Web Server: Nginx (Reverse Proxy)
  • Container Registry: Docker Hub

πŸ“ Project Structure

devops-aws/
β”œβ”€β”€ .github/
β”‚   └── workflows/
β”‚       └── deploy-to-ec2.yml    # GitHub Actions CI/CD workflow
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ build-and-push.sh        # Build & push Docker images
β”‚   └── deploy.sh                # Deploy script for EC2
β”œβ”€β”€ server/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   └── index.ts             # Express application entry point
β”‚   β”œβ”€β”€ Dockerfile               # Multi-stage Docker build
β”‚   β”œβ”€β”€ docker-compose.yml       # Container orchestration
β”‚   β”œβ”€β”€ ecosystem.config.cjs     # PM2 configuration (optional)
β”‚   β”œβ”€β”€ package.json             # Node.js dependencies
β”‚   └── tsconfig.json            # TypeScript configuration
β”œβ”€β”€ deploy.md                    # Detailed deployment guide
β”œβ”€β”€ deployed-pic.png             # Deployment screenshot
└── README.md                    # This file

πŸ“¦ Prerequisites

Local Development

  • Node.js 20 or higher
  • npm or yarn
  • Docker and Docker Compose
  • Git

AWS EC2 Instance

  • Ubuntu 20.04/22.04 LTS
  • Minimum t2.micro instance
  • Security Group with ports 80, 8080, 22 open
  • Elastic IP (recommended)

GitHub Repository

  • GitHub account
  • Repository with Actions enabled
  • Docker Hub account

πŸš€ Quick Start

1. Clone the Repository

git clone <your-repo-url>
cd devops-aws

2. Install Dependencies

cd server
npm install

3. Run Locally

# Development mode
npm run dev

# Production build
npm run build
npm start

4. Run with Docker

cd server
docker-compose up -d

Access the application at http://localhost:8080

πŸ”„ CI/CD Pipeline

The GitHub Actions workflow automatically:

  1. Build Stage:

    • Checks out the repository
    • Generates image tag from Git SHA
    • Builds Docker image
    • Pushes to Docker Hub
  2. Deploy Stage:

    • Copies necessary files to EC2
    • Pulls the latest Docker image
    • Performs zero-downtime deployment
    • Validates health checks

Workflow Triggers

The pipeline runs automatically on:

  • Push to main branch

🎯 Deployment Process

Initial EC2 Setup

1. Update System Packages

sudo apt update && sudo apt upgrade -y

2. Install Node.js

sudo apt-get install npm -y
sudo npm i -g n
sudo n lts

3. Install Docker

# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Add user to docker group
sudo usermod -aG docker $USER

# Install Docker Compose
sudo apt-get install docker-compose-plugin -y

4. Install & Configure Nginx

# Install Nginx
sudo apt install nginx -y

# Start and enable
sudo systemctl start nginx
sudo systemctl enable nginx

5. Configure Nginx Reverse Proxy

Create configuration file:

sudo nano /etc/nginx/sites-available/express-app

Add the following configuration:

server {
    listen 80;
    server_name YOUR_EC2_PUBLIC_IP;

    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Enable the configuration:

sudo ln -s /etc/nginx/sites-available/express-app /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl restart nginx

6. Create Application Directory

sudo mkdir -p /home/$USER/server
cd /home/$USER/server

GitHub Secrets Configuration

Add these secrets to your GitHub repository (Settings β†’ Secrets and variables β†’ Actions):

Secret Name Description Example
DOCKERHUB_USERNAME Docker Hub username your-username
DOCKERHUB_TOKEN Docker Hub access token dckr_pat_xxx...
EC2_HOST EC2 public IP address 3.109.59.94
EC2_USER SSH username ubuntu
EC2_SSH_KEY Private SSH key Contents of .pem file
EC2_SSH_PORT SSH port (optional) 22

πŸ” Environment Variables

Application Environment Variables

Create a .env file in the server directory:

PORT=8000
NODE_ENV=production

GitHub Actions Environment Variables

Set in workflow file or repository variables:

env:
  DOCKERHUB_REPO: your-username/your-repo-name

🌐 API Endpoints

Health Check

GET /health

Response:

{
  "status": "ok",
  "timestamp": "2025-12-13T10:30:00.000Z"
}

Root Endpoint

GET /

Response:

It's working guysπŸ™Œ. Hello

πŸ”§ Manual Deployment

If you need to deploy manually:

1. Build and Push Docker Image

export DOCKERHUB_REPO=your-username/your-repo
export DOCKERHUB_USERNAME=your-username
export DOCKERHUB_TOKEN=your-token

./scripts/build-and-push.sh

2. Deploy to EC2

ssh -i your-key.pem ubuntu@your-ec2-ip

# Run deployment script
./scripts/deploy.sh your-username/your-repo:tag

πŸ“Š Monitoring & Maintenance

Check Application Status

# Check Docker containers
docker ps

# View logs
docker logs express-app

# Check Nginx status
sudo systemctl status nginx

Verify Deployment

# Check health endpoint
curl http://your-ec2-ip/health

# Or visit in browser
http://your-ec2-ip/

View Application Logs

# Real-time logs
docker logs -f express-app

# Last 100 lines
docker logs --tail 100 express-app

πŸ› Troubleshooting

Application Not Accessible

  1. Check Security Group: Ensure ports 80, 8080, and 22 are open
  2. Verify Nginx: sudo systemctl status nginx
  3. Check Docker: docker ps - container should be running
  4. View Logs: docker logs express-app

Deployment Fails

  1. Verify GitHub Secrets: All required secrets are set
  2. Check SSH Key: Ensure private key format is correct
  3. EC2 Permissions: User has docker group permissions
  4. Disk Space: df -h - ensure sufficient space

Docker Issues

# Restart Docker daemon
sudo systemctl restart docker

# Clean up unused containers/images
docker system prune -a

# Rebuild and restart
cd ~/server
docker-compose down
docker-compose up -d --build

Nginx Issues

# Test configuration
sudo nginx -t

# Restart Nginx
sudo systemctl restart nginx

# Check error logs
sudo tail -f /var/log/nginx/error.log

πŸ“ Additional Notes

  • Zero Downtime: The deployment script performs health checks before marking deployment as successful
  • Image Tagging: Images are tagged with Git SHA (first 7 characters)
  • Rollback: Previous images are retained in Docker Hub for easy rollback
  • Security: Never commit secrets or private keys to the repository

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Push to the branch
  5. Open a Pull Request

πŸ“„ License

This project is open source and available under the MIT License.

πŸ‘€ Author

Created with ❀️ for learning DevOps practices


Need Help? Check deploy.md for detailed deployment instructions.

About

Automated CI/CD pipeline for deploying Express.js TypeScript app to AWS EC2 using Docker, GitHub Actions, and Nginx

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages