π TypeScript Backend - AWS EC2 Deployment Guide
Complete step-by-step guide to deploy a TypeScript Node.js backend to AWS EC2 with Redis, Nginx, SSL, and PM2.
π Pre-Deployment Checklist
Before starting, make sure you have:
- [ ] AWS IAM credentials with EC2 access
- [ ] MongoDB Atlas production database ready
- [ ] All production credentials (Firebase, payment gateway, etc.)
- [ ] Code pushed to GitHub
mainbranch - [ ]
npm run buildworks locally without errors - [ ] Domain name purchased and accessible
π Replace These Placeholders
Throughout this guide, replace these with your actual values:
| Placeholder | Example | Your Value |
|---|---|---|
YOUR_PROJECT_NAME |
loopcall-backend | ___ |
YOUR_DOMAIN |
api.example.com | ___ |
YOUR_PUBLIC_IP |
13.235.xxx.xxx | ___ |
YOUR_GITHUB_URL |
https://github.com/user/repo.git | ___ |
YOUR_PORT |
8000 | ___ |
Part 1: Create EC2 Instance
Step 1.1: Login to AWS Console
- Go to AWS Console
- Login with your IAM credentials
- Select your preferred region (e.g., Mumbai
ap-south-1)
Step 1.2: Launch EC2 Instance
-
Go to EC2 Dashboard β Click Launch Instance
-
Name your instance:
YOUR_PROJECT_NAME -
Choose AMI (Amazon Machine Image):
- Select Ubuntu Server 22.04 LTS (HVM), SSD Volume Type
- Architecture: 64-bit (x86)
-
Choose Instance Type:
- Select t2.micro (Free Tier) or t2.small for more traffic
-
Create Key Pair:
- Click Create new key pair
- Name:
YOUR_PROJECT_NAME-key - Type: RSA
- Format: .pem
- Click Create key pair - β οΈ SAVE THIS FILE SECURELY!
-
Network Settings:
- Click Edit
- Keep default VPC
- Auto-assign public IP: Enable
- Create security group with name:
YOUR_PROJECT_NAME-sg
-
Configure Security Group Rules:
Type Port Range Source Description SSH 22 My IP SSH access HTTP 80 0.0.0.0/0, ::/0 Web traffic HTTPS 443 0.0.0.0/0, ::/0 Secure web traffic Custom TCP YOUR_PORT 0.0.0.0/0, ::/0 Node.js app (temporary) -
Configure Storage:
- Keep default 8 GB or increase to 20 GB if needed
-
Click Launch Instance
Step 1.3: Wait for Instance to Start
- Go to EC2 Dashboard β Instances
- Wait until Instance State shows Running (green)
- Wait until Status checks shows 2/2 checks passed
- Copy the Public IPv4 address - you'll need this!
Part 2: Connect to EC2 via SSH
Step 2.1: Open PowerShell
- Open PowerShell (search in Start menu)
- Navigate to folder where
.pemfile is saved:cd Downloads
Step 2.2: Connect via SSH
ssh -i "YOUR_PROJECT_NAME-key.pem" ubuntu@YOUR_PUBLIC_IP
First time connecting? Type yes when asked about fingerprint.
β
You should now see: ubuntu@ip-xxx-xxx-xxx-xxx:~$
Part 3: Install Required Software
Step 3.1: Update System Packages
sudo apt update && sudo apt upgrade -y
Step 3.2: Install Node.js 20.x
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
Verify installation:
node -v # Should show v20.x.x
npm -v # Should show 10.x.x
Step 3.3: Install Git
sudo apt install git -y
git --version
Step 3.4: Install Redis (if your project uses Redis)
sudo apt install redis-server -y
sudo systemctl enable redis-server
sudo systemctl start redis-server
Verify Redis:
redis-cli ping # Should return: PONG
Step 3.5: Install PM2 (Process Manager)
sudo npm install -g pm2
pm2 --version
Step 3.6: Install Nginx (Web Server)
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
Verify Nginx:
sudo systemctl status nginx # Should show: active (running)
Part 4: Clone and Setup Application
Step 4.1: Generate GitHub Token (for private repos)
- Go to: https://github.com/settings/tokens
- Click Generate new token (classic)
- Name:
EC2-YOUR_PROJECT_NAME - Expiration: No expiration
- Check: β
repo - Click Generate token and COPY IT!
Step 4.2: Clone Repository
cd ~
git clone https://[email protected]/USERNAME/REPO_NAME.git
cd REPO_NAME
Step 4.3: Install Dependencies
npm install
Step 4.4: Create Environment File
nano .env
Paste your production environment variables, then save:
- Press
Ctrl + X - Press
Y - Press
Enter
Verify .env file:
cat .env
Step 4.5: Build TypeScript
npm run build
Verify build:
ls dist/ # Should show server.js and other files
Part 5: Start Application with PM2
Step 5.1: Start the Application
pm2 start dist/server.js --name "YOUR_PROJECT_NAME"
Step 5.2: Verify Application is Running
pm2 status
Step 5.3: Check Logs
pm2 logs YOUR_PROJECT_NAME
Step 5.4: Configure PM2 to Auto-Start on Reboot
pm2 startup
Copy and run the command it shows, then:
pm2 save
Step 5.5: Test Application
curl http://localhost:YOUR_PORT/health
Part 6: Configure Nginx as Reverse Proxy
Step 6.1: Edit Nginx Configuration
sudo nano /etc/nginx/sites-available/default
Delete everything and paste this:
server {
listen 80;
listen [::]:80;
server_name YOUR_DOMAIN;
location / {
proxy_pass http://localhost:YOUR_PORT;
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;
# WebSocket support for Socket.IO
proxy_read_timeout 86400;
}
}
Save and exit.
Step 6.2: Test Nginx Configuration
sudo nginx -t
Step 6.3: Restart Nginx
sudo systemctl restart nginx
Step 6.4: Test via Public IP
Open browser: http://YOUR_PUBLIC_IP/health
Part 7: Configure Domain DNS
Step 7.1: Get Your EC2 Public IP
curl ifconfig.me
Step 7.2: Add DNS Records
In your domain registrar, add:
| Type | Name | Value | TTL |
|---|---|---|---|
| A | api | YOUR_PUBLIC_IP | 300 |
For root domain and www: | Type | Name | Value | TTL | |------|------|-------|-----| | A | @ | YOUR_PUBLIC_IP | 300 | | A | www | YOUR_PUBLIC_IP | 300 |
Step 7.3: Test DNS
Wait 5-30 minutes, then:
curl http://YOUR_DOMAIN/health
Part 8: Install SSL Certificate (HTTPS)
Step 8.1: Install Certbot
sudo apt install certbot python3-certbot-nginx -y
Step 8.2: Get SSL Certificate
sudo certbot --nginx -d YOUR_DOMAIN
When prompted:
- Enter email address
- Agree to terms:
Y - Share email with EFF:
N - Redirect HTTP to HTTPS:
2
Step 8.3: Verify SSL Auto-Renewal
sudo certbot renew --dry-run
Step 8.4: Test HTTPS
Open browser: https://YOUR_DOMAIN/health
Part 9: MongoDB Atlas - Whitelist EC2 IP
- Go to MongoDB Atlas
- Go to your cluster β Network Access
- Click Add IP Address
- Add:
YOUR_PUBLIC_IP/32 - Description:
EC2 Production Server
π Useful PM2 Commands
| Command | Description |
|---|---|
pm2 status |
Check application status |
pm2 logs YOUR_PROJECT_NAME |
View real-time logs |
pm2 logs YOUR_PROJECT_NAME --lines 100 |
View last 100 logs |
pm2 restart YOUR_PROJECT_NAME |
Restart application |
pm2 stop YOUR_PROJECT_NAME |
Stop application |
pm2 delete YOUR_PROJECT_NAME |
Remove from PM2 |
pm2 monit |
Real-time monitoring |
π How to Deploy Updates
cd ~/REPO_NAME
git pull origin main
npm install
npm run build
pm2 restart YOUR_PROJECT_NAME
β οΈ Troubleshooting
Application not starting?
pm2 logs YOUR_PROJECT_NAME --lines 50
Nginx errors?
sudo nginx -t
sudo tail -f /var/log/nginx/error.log
Redis not working?
sudo systemctl status redis-server
redis-cli ping
MongoDB connection failed?
- Check if EC2 IP is whitelisted in MongoDB Atlas
- Verify connection string in
.env
Port already in use?
sudo lsof -i :YOUR_PORT
pm2 delete all
pm2 start dist/server.js --name "YOUR_PROJECT_NAME"
Certbot "already running" error?
sudo pkill certbot
sudo certbot --nginx -d YOUR_DOMAIN
β Deployment Complete!
Your backend is now:
- β Running on EC2 with PM2
- β Behind Nginx reverse proxy
- β Secured with SSL (HTTPS)
- β Auto-restarts on crash/reboot
π€ Author
Sameen K A - CTO at Veevity Technologies