Host Your Static Website and Node.js API on EC2 Using Nginx
Learn how to deploy a static website and a Node.js backend API on an AWS EC2 instance using Nginx and PM2. This step-by-step guide covers everything from SSH access to process management, making your setup production-ready.
Table of Contents
File Permissions and SSH Keys
SSH into EC2
Update Packages
Install Nginx
Start & Enable Nginx
Test with curl
Copy Files from WSL to EC2
Move Files to Nginx Root
Install Node.js Using NVM
Install PM2
Start Node.js API with PM2
Configure Nginx Reverse Proxy
Next Steps / Tips
1️⃣ File Permissions and SSH Keys
chmod 400 ~/DevOps.pem
What it does: Sets permissions so only the owner can read the private key.
Purpose: SSH requires strict key permissions for security.
Tip: Without this, SSH will refuse to use your
.pemkey.
2️⃣ SSH into EC2
ssh -i ~/DevOps.pem ec2-user@YOUR_PUBLIC_IP
ssh→ connects securely to your EC2 instance.-i ~/DevOps.pem→ specifies the private key for authentication.Purpose: Gain access to manage your server remotely
3️⃣ Update Packages (Amazon Linux)
sudo yum update -y
- Purpose: Keeps the system secure and prepares it for new software.
4️⃣ Install Nginx
sudo yum install nginx -y
- Purpose: Installs Nginx web server to serve static content and act as a reverse proxy.
5️⃣ Start & Enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
start→ starts Nginx immediately.enable→ ensures Nginx runs after reboot.Purpose: Keep your web server running persistently.
6️⃣ Test with curl
Basic test
curl http://localhost
- Checks if Nginx is serving content.
Check HTTP headers
curl -I http://localhost
-
-I→ fetch only HTTP headers to verify status code (200 OK).
7️⃣ Copy Files from WSL to EC2
scp -i ~/DevOps.pem -r ~/DevOps ec2-user@YOUR_PUBLIC_IP:/home/ec2-user/
scp→ securely copies files over SSH-r→ recursive copy (entire folder)Purpose: Deploy your local project to the EC2 instance
8️⃣ Move Files to Nginx Root
sudo mv ~/DevOps /usr/share/nginx/html/
sudo chmod -R 755 /usr/share/nginx/html/DevOps
mv→ moves files/folderschmod -R 755→ owner can write, everyone else can read/executePurpose: Make static site accessible via Nginx
9️⃣ Install Node.js Using NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.6/install.sh | bash
source ~/.bashrc
nvm install --lts
nvm alias default lts/*
Step-by-step:
curl -o- URL | bash→ downloads and installs NVMsource ~/.bashrc→ loads NVM into current shellnvm install --lts→ installs latest Node.js LTSnvm alias default lts/*→ makes LTS version the default in all new shellsPurpose: Safely manage Node.js versions; ensures your backend always runs on the latest stable LTS.
10️⃣ Install PM2
npm install -g pm2
npm→ Node.js package manager-g→ global installPurpose: Install PM2, a process manager for Node.js, to keep your API running in the background.
11️⃣ Start Node.js API with PM2
pm2 start ~/api/server.js --name my-api
pm2 start→ runs your Node.js API under PM2 supervision--name→ gives the process a friendly name for easy managementPurpose: Keep your API running continuously; auto-restarts if it crashes.
⚠️ Note: server.js must exist at ~/api/server.js before running this command. PM2 cannot create the file for you.
12️⃣ Configure Nginx Reverse Proxy
sudo tee /etc/nginx/conf.d/reverse.conf > /dev/null <<'EOF'
server {
listen 80;
location / {
root /usr/share/nginx/html/DevOps;
index index.html;
}
location /api/ {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
sudo nginx -t
sudo systemctl reload nginx
tee→ writes the config filenginx -t→ tests for syntax errorssystemctl reload nginx→ reloads configuration without downtimePurpose: Serve your static site and forward /api requests to your Node.js backend
13️⃣ Next Steps / Tips
Use
pm2save andpm2 startupto ensure Node.js API restarts after EC2 reboot.Add HTTPS using Certbot + Nginx for a secure website.
For frequent deployments, consider
rsync -avzinstead ofscpto sync only changed files.Monitor logs with
pm2 logs my-apito troubleshoot your backend.
✅ Key Categories
| Category | Commands | Purpose |
|---|---|---|
| SSH / File transfer |
ssh, scp
|
Connect and deploy files to EC2 |
| Package management |
yum update, apt update
|
Keep system up-to-date |
| Web server |
nginx, systemctl start/enable
|
Serve static content & reverse proxy |
| Testing | curl |
Verify server & headers |
| Node.js management |
nvm install --lts, nvm alias default
|
Install latest LTS Node |
| Process management |
npm install -g pm2, pm2 start
|
Keep API running |
| Permissions & deployment |
chmod, mv
|
Ensure proper file access for web serving |
| Nginx config |
tee /etc/nginx/conf.d/..., nginx -t, systemctl reload
|
Configure reverse proxy and static site |
Top comments (0)