Deploying a Next.js application to an AWS EC2 instance is a common production pathway for modern web apps. However, while the deployment process looks straightforward, developers often encounter issues with SSH access, Linux permissions, missing libraries, Nginx conflicts, and more.
This guide outlines a clean, step-by-step method to deploy a Next.js frontend to an Ubuntu EC2 instance—along with the most common errors you may encounter and how to resolve them.
Infrastructure Overview
Cloud Platform: AWS EC2 (Ubuntu)
Frontend: Next.js (React)
Runtime: Node.js (installed via NVM)
Process Manager: PM2
Reverse Proxy: Nginx
Local Machine: Windows (with WSL Ubuntu terminal)
Step 1: Connect to EC2 via SSH
After launching the EC2 instance, the first task is to connect through SSH using your .pem key.
Common Error 1: “Unprotected Private Key File”
Cause:
The .pem file is stored on the Windows file system (/mnt/c/...).
NTFS permissions do not map correctly to Linux, so chmod does not work.
Fix: Move the key to the Linux file system and reapply permissions:
cp /mnt/c/path/to/my-key.pem ~
cd ~
chmod 400 my-key.pem
Common Error 2: “Connection Timed Out”
Cause:
Inbound SSH traffic (port 22) is not allowed in the EC2 security group.
Fix:
Go to AWS Console → EC2 → Security Groups
Edit Inbound Rules
Add:
Type: SSH
Port: 22
Source: Your IP (recommended)
Then connect:
ssh -i "my-key.pem" ubuntu@<public-ip>
Step 2: Install Node.js & Fix Missing Libraries
Install Node.js using NVM (recommended for version management):
sudo apt update
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
source ~/.bashrc
nvm install node
nvm alias default node
Common Error 3: “libatomic.so.1: cannot open shared object file”
Cause:
Minimal Ubuntu images may not include a required library for newer Node.js versions.
Fix:
sudo apt-get install libatomic1
Step 3: Clone, Install, Build, and Run the App
Clone your repository:
git clone https://github.com/your-username/your-repo.git
cd your-repo
Install dependencies and build:
npm install
npm run build
Start the app using PM2 so it keeps running after you close SSH:
npm install -g pm2
pm2 start npm --name "next-frontend" -- start
Check PM2 logs (optional):
pm2 logs next-frontend
Step 4: Configure Nginx as a Reverse Proxy
Nginx will forward requests from port 80 → port 3000.
Create a configuration file:
sudo nano /etc/nginx/sites-available/next-frontend
Add this block:
server {
listen 80;
server_name serverName;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/next-frontend /etc/nginx/sites-enabled/
Restart Nginx:
sudo systemctl restart nginx
Step 5: Fix “Welcome to Nginx” Showing Instead of Your App
If visiting the server’s public IP still shows:
Common Error 4 :Welcome to Nginx!
Cause:
The default Nginx config is still active and overriding your new configuration.
Fix: Remove the default config:
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl restart nginx
Reload your browser — your Next.js app should now appear.
Final Quick Commands (Reference Sheet)
Purpose Command
SSH into server ssh -i key.pem ubuntu@public-ip
Fix key permissions chmod 400 key.pem
Install Node via NVM nvm install node
Build Next.js app npm run build
Start app with PM2 pm2 start npm --name "app" -- start
Restart Nginx sudo systemctl restart nginx
View PM2 apps pm2 list
Conclusion
Deploying a Next.js application on AWS EC2 involves working across Linux permissions, networking rules, process management, and web server configuration. The errors you encounter—SSH permission issues, timeouts, missing libraries, or Nginx conflicts—are common and straightforward to resolve once you understand their causes.
With this guide, you should be able to deploy your app smoothly and troubleshoot the most frequent problems along the way.
Top comments (0)