Self-Hosting 101
Move from managed hosting to self-hosting on your own AWS EC2 instance.
Self-Hosting 101 (Advanced Setup)
Own the infrastructure when you graduate from Vercel’s free tier. Follow the checklist to spin up an EC2 box, deploy manually with pnpm, and keep it running.
Quick Checklist
- Confirm GitHub, Git, Node.js, Supabase access from Dev Environment Setup.
- Install
pnpmand prove the app builds locally. - Create an AWS account and launch a Ubuntu EC2 instance.
- SSH in, install Node.js + pnpm, clone your repo.
pnpm install,pnpm build,pnpm starton the server.- Add PM2 (optional) and wire up a custom domain if needed.
1. Local Pre-Flight
- Install pnpm once:
npm install -g pnpm→ verify withpnpm --version. - From your project root:
pnpm install
pnpm build
pnpm start # visit http://localhost:3000- Commit and push the working state to GitHub so the server can pull it.
2. AWS Account & Instance
- Sign in at aws.amazon.com → choose the Free Tier.
- Search for EC2 → Launch instance with:
- Name
nextjs-server - Ubuntu 24.04 LTS
t2.micro(Free Tier)- New key pair (
.pemdownload) - Allow HTTP (80) and HTTPS (443)
- Wait for the instance to boot, copy the Public IPv4 DNS.
SSH in:
chmod 400 your-key.pem
ssh -i your-key.pem ubuntu@ec2-xx-xx-xx-xx.compute-1.amazonaws.com3. Prepare the Server
Run these commands on the EC2 shell:
sudo apt update
sudo apt install -y git curl
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
sudo npm install -g pnpm
node --version && pnpm --versionStore environment variables (Supabase keys, etc.) in a .env file or the shell profile; keep secrets out of git.
4. Deploy from GitHub
git clone https://github.com/yourusername/your-repo.git
cd your-repo
cp .env.production .env # if you keep a template
pnpm install
pnpm build
pnpm startVisit http://<your-public-dns> in the browser—your Next.js app should load. Use Ctrl + C to stop the process.
5. Keep It Running (PM2)
sudo npm install -g pm2
pm2 start "pnpm start" --name "nextjs-app"
pm2 save
pm2 startup # follow the printed instructions onceUseful checks:
pm2 status— ensure the process is onlinepm2 logs nextjs-app— view runtime logssudo reboot→pm2 resurrect(if needed after reboot)
6. Optional: Custom Domain
- Buy a domain (Namecheap, etc.).
- In AWS Route 53 → Hosted Zone → create an A record pointing to the EC2 public IP.
- Update nameservers with your registrar to the ones Route 53 provides.
- Consider adding Nginx + SSL (Let’s Encrypt) once traffic increases.
Validation Loop
| Stage | Command | What to check |
| Local | pnpm dev | UI works while coding |
| Local production | pnpm build && pnpm start | Bundled app renders |
| Remote build | pnpm install && pnpm build | Dependencies available |
| Remote runtime | pm2 status | App stays online after deploy |
Log any failures in Troubleshooting & Logs with the command you ran and the error snippet.
Practice Challenge
- Create a test Next.js app with
pnpm create next-app. - Push it to GitHub and deploy to EC2 using the flow above.
- Add a
/statusroute that prints environment info. - Confirm you can reach
/statusfrom the public URL.
You now control the full stack—from prompts to production hardware.