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
- Launch an Ubuntu EC2 instance.
- SSH into the instance:
ssh -i your-key.pem ubuntu@your-ec2-public-ip
- Install Docker:
sudo apt update
sudo apt install docker.io -y
sudo usermod -aG docker ubuntu
- (Optional) Install Docker Compose if needed.
🔐 Step 5: Set Up SSH Access from GitHub Actions to EC2
- Generate SSH keys locally (if not already):
ssh-keygen -t rsa -b 4096 -C "ci-cd-deploy"
- Add the public key (
.pub
) to/home/ubuntu/.ssh/authorized_keys
on your EC2 instance. - 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/[email protected]
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
- How to Build a CI/CD Pipeline with GitHub Actions and Docker – Step-by-Step
- Top GitHub Actions Every DevOps Engineer Should Know
- Deploying Node.js Apps on AWS with Docker – Beginner’s Guide
🙌 Support & Follow
Follow me on Twitter, LinkedIn, and stay tuned for more content!