Pi-Hole + Self-Hosted Web on Pi Zero 2 W
This was a quiet but satisfying project. Not flashy, no bots or AI this time — just practical infrastructure at home.
I wanted to combine two things: a Pi-Hole network-wide ad blocker and a self-hosted personal website. Both running off a single Raspberry Pi Zero 2 W. It’s cheap, small, and sips power. Seemed like the perfect candidate for something that’s meant to stay on 24/7.
I flashed a high-endurance SD card — the type made for continuous operation — and set up the Pi with an Ethernet adapter via micro-USB. Wi-Fi would’ve been easier, but I didn’t want to risk instability.
Setting up Pi-Hole was mostly painless. Installed it via the official script and pointed my router’s DNS to the Pi’s local IP. Ads vanished instantly across all devices. Well — most of them. I noticed a lot of Google ads slipping through. So I added a few aggressive blocklists and manually blacklisted the domains that slipped past.
That was step one. Step two: turn the same Pi into a web server for my personal site. Resource-wise, the site is featherlight. I knew the Pi could handle it easily, and it just made sense to combine both roles into one always-on node.
I installed Nginx, set it to listen on a custom port, and configured the Pi to use a static IP. Then I set up port forwarding (NAT) on my router to expose the Nginx port to the internet.
Except… it didn’t work.
I could open the site from inside my network — via the Pi’s local IP, even through my desktop and the router’s address. But accessing it from my public IP? Nothing.
I retraced every step. Verified the NAT rule. Tried different ports. Restarted everything. Still nothing. Then I remembered something: my router doesn’t actually connect directly to the internet — it’s plugged into another device I had set up as an “access point.”
That was the missing piece. Except, it turns out that device wasn’t just an access point — it was acting as a router in disguise.
I had unknowingly created a double NAT situation: one router behind another. And that breaks public port forwarding unless both routers are configured to cooperate. I tried enabling NAT and port forwarding on the outer device, but it didn’t help. Forums confirmed what I was running into — unless the outer device is in bridge mode or the inner one is placed in a DMZ, public IP routing won’t behave properly.
DMZ, or Demilitarized Zone, is a router setting that exposes one internal device (like your Pi) directly to the internet. It bypasses firewall and NAT restrictions from the outer router, effectively treating that device as if it’s sitting on the public internet — which allows things like port forwarding to work through double NAT. It’s handy, but comes with security risks since the device is no longer protected by the router’s firewall.
So now I have options. I can either restructure my network — maybe put the main router into bridge mode or flatten everything into one device — or just accept that this is a LAN-only server for now.
Still — Pi-hole works beautifully. The site is accessible from inside the network. And the little Pi is pulling double-duty like a champ.