What are we actually building?
Have you ever pushed a project to Vercel and noticed you get a URL like my-app-git-main-yourname.vercel.app within seconds? Each deployment gets its own subdomain, its own isolated environment, and it just works.
Have you wondered what's actually happening under the hood? There's no magic — it's a combination of a reverse proxy, subdomain routing, and some smart file serving. And we're going to build exactly that ourselves, step by step, across this series.
Here's the rough plan across the four parts:
- →Part 1 (this one) — spin up an EC2 instance, install Nginx, confirm it's running
- →Part 2 — configure Nginx to route subdomains to different folders
- →Part 3 — handle file uploads and connect an S3 bucket
- →Part 4 — wire it all together into one working deployment flow
By the end of Part 1, your goal is simple: visit your EC2 instance's public IP in a browser and see the Nginx welcome page. That's it. Small win, solid foundation.
Why Nginx?
Nginx (pronounced engine-x) is one of those tools that shows up everywhere once you start looking — and for good reason. It's open source, insanely performant, and used by some of the largest platforms in the world.
For our purposes, Nginx does a few key things:
- →Reverse proxy — receives a request and forwards it to the right place
- →Subdomain routing — checks the Host header and decides where to send traffic
- →Static file serving — can serve HTML/CSS/JS directly without a Node process
- →Load balancing — distribute traffic across multiple servers (we'll get there)
For this series, Nginx is the core piece that makes subdomain mapping possible. When a request comes in for abc123.yourdomain.com, Nginx intercepts it, reads the subdomain, and serves the matching project files. That's the whole trick.
Step 1 — Create an EC2 Instance
You need a server. For this series we'll use AWS EC2, but Google Cloud Compute or any VPS (DigitalOcean, Hetzner) works fine — the setup is identical once you're inside the terminal.
Launch the instance
Go to AWS Console → EC2 → Launch Instance. Pick Ubuntu 22.04 LTSas your AMI — it's free tier eligible and has the best community support. For instance type, t2.micro is fine to start.
Download your .pem key
When prompted to create a key pair, download the .pemfile and keep it safe. You'll use this to SSH into the instance. You can't download it again.
Set up the Security Group
This is the firewall. You need to open two ports in the inbound rules:
In production you'd restrict SSH to your own IP, but for now this is fine.
SSH into the instance
Once the instance is running, grab the public IP from the console and connect:
You should land in the Ubuntu terminal. If you're seeing a connection refused error, the instance is probably still initializing — wait 30 seconds and retry.
3.84.xx.xx. Note that it changes every time you stop and restart the instance — we'll deal with that in a later part using an Elastic IP.Step 2 — Run the Setup Script
Once you're inside the server, here's the setup script. It installs Nginx, Node.js 20, npm, git, and creates the directory structure we'll use to serve project files later.
You can either paste this line by line or save it as a setup.sh file and run it:
nginx.conffile in this script — we'll write that properly in Part 2 when we set up subdomain routing. For now, Nginx's default config is already enough to confirm everything is working.Step 3 — Confirm Nginx Is Running
After the script finishes, check that Nginx started correctly:
If it says active (running)— you're good. Now open your browser and visit your EC2 instance's public IP:
✓ What you should see
A plain white page that says "Welcome to nginx!" with some text below it. That's the default Nginx page. If you're seeing it — Nginx is running, your security group is open, and the server is reachable. That's everything we need for Part 1.
http:// not https://— we haven't set up SSL yet. Your browser might try to redirect you to HTTPS automatically. If the page doesn't load, force http://YOUR_IP in the address bar.Troubleshooting
SSH: Permission denied
Run chmod 400 your-key.pem first. The key file permissions have to be restricted.
Browser: connection timed out
Check your security group. Port 80 (HTTP) must be open with source 0.0.0.0/0.
Nginx not starting
Run sudo nginx -t to check for config errors. Also check sudo journalctl -u nginx for logs.
Page loads but shows default Apache page
Apache might already be installed. Run sudo systemctl stop apache2 && sudo systemctl start nginx.
Where We Are
That's Part 1 done. You have a live Ubuntu server on EC2, Nginx is installed and running, and you can hit it from a browser. It's not doing anything useful yet — but the foundation is in place.
In Part 2, we get into the actual interesting part: configuring Nginx to read the subdomain from an incoming request and route it to the right folder. That's the core mechanism behind how Vercel (and tools like it) work. See you there.