Skip to main content

Command Palette

Search for a command to run...

πŸš€ Deploy Node.js to AWS EC2 Using .pem Key and GitHub Actions (CI/CD)

Published
β€’4 min readβ€’View as Markdown

If you're a developer or DevOps beginner looking to automate your Node.js app deployment from GitHub to an AWS EC2 instance, this guide is for you. We'll cover everything from launching an EC2 instance to deploying via GitHub Actions using a .pem file.


πŸ“¦ Prerequisites

  • AWS Account (Free tier is fine)

  • GitHub account with your Node.js app repo

  • Basic terminal skills

  • Node.js installed in your project


🧱 Step 1: Launch EC2 Instance

βœ… 1.1 Go to EC2 Console

βœ… 1.2 Configure Instance

  • Name: GitHub-CI-CD-Server

  • OS Image: Ubuntu 24.04 LTS

  • Instance Type: t2.micro (Free Tier eligible)

  • Key Pair: Click "Create Key Pair"

    • Name: GitHub-CI-CD-Server-key

    • Type: RSA

    • File format: .pem

    • Download the .pem and store it safely


πŸ” Step 2: Set Inbound Security Rules

During instance setup β†’ Network settings:

βœ… Inbound rules:

TypePortSource
SSH22Anywhere
HTTP80Anywhere
Custom TCP3000Anywhere

βœ… Now click Launch Instance
πŸ”’ Important: Later, restrict SSH access to My IP for security.


πŸ’» Step 3: Connect to EC2 with .pem

Open terminal or WSL and navigate to the folder where .pem is stored:

chmod 400 GitHub-CI-CD-Server-key.pem
ssh -i GitHub-CI-CD-Server-key.pem ubuntu@<your-ec2-ip>

You’re now inside your EC2 machine πŸŽ‰


βš™οΈ Step 4: Set Up Node.js on EC2

sudo apt update
sudo apt install nodejs npm -y

You can test with:

node -v
npm -v

πŸ“ Step 5: Set Up GitHub Repository

Make sure your project includes:

  • index.js or app.js

  • package.json


πŸ›‘οΈ Step 6: Add .pem to GitHub Secrets (Encrypted)

GitHub doesn’t allow file uploads, but we can convert .pem to a string:

βœ… 6.1 Convert .pem to base64 string

base64 GitHub-CI-CD-Server-key.pem

Copy the long string inside .pem

A .pem (Privacy Enhanced Mail) file is a Base64-encoded file format commonly used to store private keys, certificates, and public keys in the context of secure communication, especially SSH access.

πŸ›‘ Example .pem File Structure

When you download a .pem file from AWS (like GitHub-CI-CD-Server-key.pem), it looks like this:

vbnetCopyEdit-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAx8+JhBdLqGRX...
...many lines of characters...
...never share this file...
...this is your private key...
-----END RSA PRIVATE KEY-----
  • BEGIN/END lines are delimiters

  • Contents between are the private RSA key, used to authenticate SSH sessions

  • Do not share this file publicly; it gives full access to your server

βœ… 6.2 Add GitHub Secrets

Go to your GitHub repo β†’ Settings β†’ Secrets β†’ Actions

Add these secrets:

NameValue
PEM_KEY(Paste the base64 encoded key)
EC2_HOST<your-ec2-public-ip>
EC2_USERubuntu

βš™οΈ Step 7: Create GitHub Actions Workflow

In your project repo:

mkdir -p .github/workflows
touch .github/workflows/deploy.yml

Paste the following:

name: Deploy to EC2 using PEM

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

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

      - name: Decode PEM file
        run: |
          echo "${{ secrets.PEM_KEY }}" | base64 -d > key.pem
          chmod 400 key.pem

      - name: Deploy to EC2
        run: |
          ssh -o StrictHostKeyChecking=no -i key.pem ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} << 'EOF'
            pkill node || true
            rm -rf ~/app
            mkdir ~/app
            cd ~/app
            echo "const http = require('http'); const PORT = 3000; http.createServer((req, res) => res.end('Hello from GitHub Actions!')).listen(PORT);" > index.js
            nohup node index.js > out.log 2>&1 &
          EOF

🌐 Step 8: Test Deployment

Push your code to main:

git add .
git commit -m "Deploy via GitHub Actions"
git push origin main

After a minute, visit:

http://<your-ec2-ip>:3000

You should see:

Hello from GitHub Actions!

πŸ›‘οΈ Best Practices

  • Never expose .pem directlyβ€”use GitHub secrets

  • Use pm2 for production process management

  • Add a reverse proxy (e.g. Nginx)

  • Restrict SSH port access to your IP only


βœ… Summary

StepDone βœ…
Launched EC2 instanceβœ…
Connected with .pemβœ…
Installed Node.jsβœ…
Created GitHub Actionsβœ…
Auto-deployed Node appβœ…

🧾 Conclusion

Congratulations! You’ve successfully deployed your Node.js application to AWS EC2 using GitHub Actions and a .pem file. This setup enables continuous deployment with every code push, making your delivery process smooth, scalable, and hands-free.

For production-ready deployments, consider adding:

  • pm2 for process management

  • Reverse proxy with Nginx

  • HTTPS using Let’s Encrypt

  • Environment variable management with .env or AWS Systems Manager


πŸ”— Reference

You can find the complete working example and code in this GitHub repository:

πŸ‘‰ GitHub-CI-CD-Learning by Akash