Projects

Deploying a Node.js App with GitHub Actions and Docker on AWS EC2 – Step-by-Step Guide

Are you looking to deploy your Node.js app with modern automation techniques? In this guide, you’ll learn how to use GitHub Actions, Docker, and AWS EC2 to create a production-grade deployment pipeline.


Prerequisites

Before we begin, make sure you have the following:

  • A GitHub account with your Node.js project pushed to a repository.
  • A basic Node.js app (Express, for example).
  • Docker installed locally.
  • An AWS EC2 instance (Ubuntu preferred) with SSH access.
  • A domain name (optional).

🛠 Step 1: Create Your Node.js App

If you already have one, skip this step.

mkdir my-node-app
cd my-node-app
npm init -y
npm install express

Create a simple server in index.js:

const express = require('express');
const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
  res.send('Hello from Node.js + Docker!');
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

🐳 Step 2: Dockerize the Application

Create a Dockerfile in your project root:

FROM node:18

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["node", "index.js"]

Then add a .dockerignore file:

node_modules
npm-debug.log

🔧 Step 3: Test the Docker Image Locally

docker build -t my-node-app .
docker run -p 3000:3000 my-node-app

Visit http://localhost:3000 to test the app.


☁️ Step 4: Prepare AWS EC2 for Deployment

  1. Launch an Ubuntu EC2 instance.
  2. SSH into the instance:
ssh -i your-key.pem ubuntu@your-ec2-public-ip
  1. Install Docker:
sudo apt update
sudo apt install docker.io -y
sudo usermod -aG docker ubuntu
  1. (Optional) Install Docker Compose if needed.

🔐 Step 5: Set Up SSH Access from GitHub Actions to EC2

  1. Generate SSH keys locally (if not already):
ssh-keygen -t rsa -b 4096 -C "ci-cd-deploy"
  1. Add the public key (.pub) to /home/ubuntu/.ssh/authorized_keys on your EC2 instance.
  2. In your GitHub repo, go to Settings → Secrets and variables → Actions and add the following:
Name Value
EC2_HOST Your EC2 public IP
EC2_USERNAME ubuntu
EC2_SSH_KEY Contents of your private key

🔁 Step 6: Configure GitHub Actions Workflow

Create .github/workflows/deploy.yml:

name: Deploy to EC2

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Install SSH key
        uses: webfactory/ssh-agent@v0.5.4
        with:
          ssh-private-key: ${{ secrets.EC2_SSH_KEY }}

      - name: Deploy via SSH
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }} << 'EOF'
            cd my-node-app || git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git my-node-app && cd my-node-app
            git pull origin main
            docker stop my-node-app || true
            docker rm my-node-app || true
            docker build -t my-node-app .
            docker run -d -p 3000:3000 --name my-node-app my-node-app
          EOF

📜 Make sure to replace YOUR_USERNAME/YOUR_REPO with your actual GitHub repo.


🧪 Step 7: Test Your Deployment

Push your code to the main branch, and GitHub Actions will:

  • SSH into EC2
  • Pull latest changes
  • Rebuild and restart the Docker container

Visit http://<your-ec2-ip>:3000 to see the deployed app!


🌐 Bonus (Optional): Use a Domain Name and NGINX

If you want a clean URL and HTTPS, install NGINX on EC2, configure a reverse proxy, and use Let’s Encrypt for SSL.


✅ Final Thoughts

You’ve now built a modern CI/CD pipeline using GitHub Actions, Docker, and AWS EC2. This setup is:

  • Scalable ✅
  • Cost-effective ✅
  • Beginner-friendly ✅

If this helped you, consider sharing the article or subscribing to my newsletter!


🔗 Related Posts


🙌 Support & Follow

Follow me on Twitter, LinkedIn, and stay tuned for more content!

Mo Assem

My name is Mohamed Assem, and I am a Cloud & Infrastructure Engineer with over 14 years of experience in IT, working across both Microsoft Azure and AWS. My expertise lies in cloud operations, automation, and building modern, scalable infrastructure. I design and implement CI/CD pipelines and infrastructure as code solutions using tools like Terraform and Docker to streamline operations and improve efficiency. Open to relocation to Europe for senior infrastructure and cloud engineering roles. Through my blog, TechWithAssem, I share practical tutorials, real-world implementations, and step-by-step guides to help engineers grow in Cloud and DevOps.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button