Ref :
https://github.com/gaurav157243/aws-projects/blob/main/DBOnEC2/README.MD
✅ Setting up ec2 instance :
- Login to aws console
- Create a free ec2 Instance
- SSH inside the ec2 instance (use putty/teminus for accessing in local)
Now once you are inside linux shell , install the build essentials :
Fist update the instance :
//sudo dnf update
and then install
// nodejs and npm
sudo yum -y nodejs
//install git
sudo yum -y git
// install postgres
- postgres
Inbound rules in AWS should look something like this :
Setting up elastic ip
<aside> 💡
If you don’t setup elastic IP, everytime you restart your EC2 instance , a new public ip will be generated , hence your application will break
</aside>
Associate an Elastic IP ( Optional )
- Navigate to "Elastic IPs" in the left sidebar.
- Click "Allocate Elastic IP address."
- Keep all settings default and click "Allocate."
- Select the Elastic IP, then choose "Associate Elastic IP address" from the Actions menu.
- Check "Allow this Elastic IP address to be reassociated."
- Click "Associate."
✅ Setting up Postgres Backend on EC2 instance
Install postgres on ec2 instance :
//update
sudo dnf update -y. or sudo yum update -y
// Install
sudo dnf install -y postgresql15.x86_64 postgresql15-server
//Initiate db
sudo postgresql-setup --initdb
//start
sudo systemctl start postgresql
//stop
sudo systemctl stop postgresql
// run even after ec2 closed
sudo systemctl enable postgresql
//check status
sudo systemctl status postgresql
//active
active : sudo systemctl active postgresql
Basic psql commands :
// Login inside postgres
sudo -i -u postgres or **su -u postgres**
//Open psql shell
**psl**
//list all database
postgres= \\l. or \\list
//access single database
**\\c databaas_name**
//go inside table
**\\dt
//read hidden file
ls -a
//read file
cat filename**
//close psql shel
\\q
✅ Clone your repository
git clone <reponame>
npm install
npm run build
//applocartion should run at port 3000
Test : http://<publicip>:3000
✅ Install pm2 to keep the application running :
-
Install PM2 globally:
sudo npm install -g pm2
-
Start your Next.js app in production:
npm run build # only needed the first time or after code changes pm2 start npm --name "nextjs-app" -- start
-
Save the PM2 process list so it starts on reboot:
pm2 save pm2 startup
-
Check status:
pm2 list
-
Delete pm2 process :
pm2 stop <id or name>
✅ Install & Configure Nginx
What is nginx ?
<aside> 💡
- Nginx (pronounced Engine-X) is a high-performance web server.
- It can also work as a reverse proxy, load balancer, and HTTP/HTTPS server. </aside>
Why do we need it ?
<aside> 💡
- Serve traffic on standard ports →
- Instead of visiting
http://ip:3000
, Nginx listens on port 80 (HTTP) and 443 (HTTPS). - It forwards requests to your Node.js app (e.g., running on port 3000).
- Instead of visiting
- Enable HTTPS (SSL/TLS) →
- Nginx makes it easy to add free SSL certificates (via Certbot).
- So your site can run securely on
https://yourdomain.com
.
- Stability & Performance →
- Handles thousands of connections efficiently.
- Protects your Node.js app from crashing under heavy traffic.
- Reverse Proxy →
- Hides your backend (Node.js on port 3000).
- Clients always hit Nginx, and Nginx forwards requests internally. </aside>
Nginx will act as a reverse proxy → so instead of hitting http://EC2_IP:3000
, you’ll just use http://EC2_IP
.
-
Step 1: Install Nginx
On Amazon Linux:
sudo amazon-linux-extras install nginx1 -y
Then start it:
sudo systemctl start nginx sudo systemctl enable nginx
Check status:
sudo systemctl status nginx
Open browser →
http://<EC2_PUBLIC_IP>
→ you should see Welcome to Nginx. -
Step 2: Configure Reverse Proxy
By default, Amazon Linux doesn’t use
/etc/nginx/sites-available
. Instead it has a main config file:/etc/nginx/nginx.conf
You can add your app config inside
/etc/nginx/conf.d/nextjs.conf
(recommended).sudo nano /etc/nginx/conf.d/nextjs.conf
Add this:
server { listen 80; server_name <your-ip or domain>; 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; } }
Save & exit (
CTRL+O
,CTRL+X
).
-
Step 3: Restart Nginx
sudo nginx -t # test config sudo systemctl restart nginx
Now your app will be available at:
http://<EC2_PUBLIC_IP>
and you don’t need to add
:3000
.❓ Why no need to add 3000 port at the end ?
<aside> 💡
→ Nginx listens on the default HTTP port 80 (and optionally HTTPS on port 443).
→ You tell Nginx to forward (proxy) requests from port 80 → 3000.
</aside>
👉 Nginx receives the request on port 80
👉 Nginx forwards it to your Next.js app on port 3000
👉 User never sees port 3000 in the browser.
✅ At this point:
- PM2 keeps your app running forever (even if EC2 restarts).
- Nginx routes traffic from port 80 to your Next.js app.
If you want to kill pm2 instance :
nginx stop <id/name>
nginx delete <id/name>
-
Doubts
Q1 : Why no need to add port at the end after installing nginx ?
<aside> 💡
→ Nginx listens on the default HTTP port 80 (and optionally HTTPS on port 443).
→ You tell Nginx to forward (proxy) requests from port 80 → 3000.
👉 Nginx receives the request on port 80
👉 Nginx forwards it to your Next.js app on port 3000
👉 User never sees port 3000 in the browser.
</aside>
Q2 : Port 80 and port 443 in nginx ?
<aside> 💡
-
Port 80 → HTTP (unsecured)
- It’s the default port for plain
http://
traffic. - Example: when you type
http://example.com
, your browser actually connects to example.com:80 by default. - That’s why you don’t need to type
:80
explicitly.
- It’s the default port for plain
-
Port 443 → HTTPS (secured with SSL/TLS)
- It’s the default port for encrypted
https://
traffic. - Example: when you type
https://example.com
, your browser connects to example.com:443 automatically. - This port requires an SSL/TLS certificate (self-signed or issued by Let’s Encrypt/other CAs). </aside>
- It’s the default port for encrypted
-
✅ Add free domain and SSL
Free Domain from Noip :
- Login to noip : No-IP
- Create a hostname
- Add your ec2 public IP
- and done ✅
Install free ssl in nginx using certbot
- Install certbot
sudo yum install -y certbot python3-certbot-nginx
//check version
certbot --version
- Edit your Nginx config file (likely
/etc/nginx/nginx.conf
or/etc/nginx/conf.d/nextjs.conf
):
server {
listen 80;
server_name whataboutcoding.com; # your domain name
location / {
proxy_pass <http://localhost:3000>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
- Reload nginx
sudo nginx -t
sudo systemctl reload nginx
- Run certbot to get SSL
sudo certbot --nginx -d yourdomain.ddns.net
- Certbot will ask:
- An email (for expiry notices).
- Agree to terms.
- Whether to redirect all HTTP → HTTPS (choose Yes).
If successful, Certbot will:
✅ Issue certificate
✅ Configure Nginx with listen 443 ssl;
✅ Redirect port 80 → 443
- Test https:
<https://yourdomain.ddns.net>
✅ Redeploy your changes
Manual way
When you make changes locally and want them on EC2:
1. Connect to EC2
ssh -i your-key.pem ec2-user@your-ec2-public-ip
or you can directly login to ec2 instance
2. Go to your app folder
cd /home/ec2-user/your-nextjs-app
3. Pull latest code
If you use GitHub:
git pull origin main
Or if you uploaded files manually, re-upload the new version.
4. Install dependencies
npm install #needed if any change in package.json
5. Build your app
npm run build
6. Restart your app (with PM2)
pm2 restart nextjs-app
If you forgot the name, list processes:
pm2 list
✅ That’s it. Your changes are live!
This is alos an automated way of deployment using github action or github webhooks or jenkins CI CD . Lets keep it for some other day.
0 Comments