The Goal
I had a news portal (Nagarik Aawaj) running on a shared VPS at IP:8085. I wanted to give it a proper domain: devdigest.bishalsunuwar.com.np, using Cloudflare for DNS and free SSL.
What I Did
- Registered bishalsunuwar.com.np on Cloudflare
- Added an A record — Name: devdigest, IPv4: my VPS IP, Proxy: ON (orange cloud)
- Set Cloudflare SSL/TLS mode to Full
- Created an nginx server block on the VPS to proxy devdigest.bishalsunuwar.com.np to 127.0.0.1:8085 Simple enough, right? Wrong.
The Problem
After everything was set up, visiting https://devdigest.bishalsunuwar.com.np loaded a completely different website — gmls.com.np, another project hosted on the same VPS.
The Debugging Process
I ran some tests on the VPS:
curl -I http://127.0.0.1:80 -H "Host: devdigest.bishalsunuwar.com.np"
This returned my Next.js app correctly — so the nginx config on port 80 was working fine.
But when accessed through Cloudflare, it kept showing the wrong site. That was the clue.
The Root Cause
When Cloudflare's SSL mode is set to Full, it connects to your server over HTTPS (port 443), not HTTP (port 80).
My devdigest nginx config only had:
listen 80;
It had no port 443 listener. Meanwhile, the gmls.com.np config had a 443 SSL block. Since nginx had no matching server for devdigest on port 443, it fell back to gmls — the only other config listening on that port.
The Fix
I added an SSL server block to my devdigest nginx config:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name devdigest.bishalsunuwar.com.np;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
location / {
proxy_pass http://127.0.0.1:8085;
# proxy headers...
}
}
The SSL certificate is just Ubuntu's default self-signed "snakeoil" cert. It doesn't matter that it's self-signed because Cloudflare handles the real SSL for visitors. The connection chain is:
User → HTTPS (valid Cloudflare cert) → Cloudflare → HTTPS (snakeoil cert) → VPS
After reloading nginx, the subdomain worked perfectly.
Key Takeaways
- DNS A records don't include port numbers — just the raw IP address
- Cloudflare "Full" SSL connects to your server on port 443 — your nginx must listen on 443, not just 80
- On a shared VPS, nginx falls back to the first available server block if no server_name matches on that port — this is how one site can "hijack" another
- Multiple sites can share port 443 — nginx uses the server_name to route requests, not the port
- Self-signed certs are fine behind Cloudflare — Cloudflare doesn't validate your origin cert in "Full" mode (only "Full Strict" does) I almost mass googled the entire issue with wrong keywords before slowing down and debugging layer by layer. If you're running multiple projects on a shared VPS behind Cloudflare, I hope this saves you the headache I went through.
Have you ever had a "one line fix" that took hours to find? Drop it in the comments — I'd love to hear your debugging war stories. And if you have questions about Cloudflare, nginx, or VPS setups, ask away — happy to help.
Top comments (0)