Practical architecture for combining Pi-hole and Nginx Proxy Manager Overview: Roles of Each Component Pi-hole Runs local DNS (port 53) Serves as the DNS resolver for your network Provides local DNS records so devices resolve service names (e.g., home.lab , jellyfin.lab ) Does not need to serve HTTP(80) or HTTPS(443) Nginx Proxy Manager (NPM) Handles all HTTP/HTTPS traffic for services Manages SSL certificates (Let’s Encrypt if you choose) Routes incoming application requests to internal services on different ports/IPs Key Principle Pi-hole handles DNS resolution only. NPM handles web traffic routing and HTTPS termination . This clear separation avoids conflicts and makes management scalable. ✔️ Best Architecture (Most Reliable) 1) Move Pi-hole’s Web UI off Port 80/443 By default Pi-hole binds its web UI to port 80/443. This collides with NPM. Change Pi-hole Admin UI to a different port (e.g., 8081 , 8888 ): On Pi-hole host: change Lighttpd config so /admin listens on 8081 DNS on Pi-hole still runs on port 53 and is unaffected by this change This allows NPM to own 80/443 exclusively. ( bolet.io ) 2) Local DNS Records in Pi-hole for All Reverse-Proxied Hosts Create A records that point friendly domains to NPM’s IP. Example: pihole.lab.zn80.net → 192.168.10.105 jellyfin.lab.zn80.net → 192.168.10.105 bookstack.lab.zn80.net → 192.168.10.105 Reasoning: Devices query Pi-hole DNS and get your internal names NPM then routes based on Host header Pi-hole is the DNS source of truth for your LAN. ( ReproDev ) 3) Configure NPM Proxy Hosts for Each Service Inside NPM Proxy Hosts : Domain/Hostname Forward To Port Notes pihole.lab.zn80.net 192.168.10.105 8081 Pi-hole admin UI jellyfin.lab.zn80.net 192.168.10.xxx 8096 Jellyfin service bookstack.lab.zn80.net … … Other services Important details For Pi-hole you may need to forward /admin correct paths Enable SSL for all hosts (ideally) via Let’s Encrypt (even internal DNS) If Let’s Encrypt can’t validate via DNS challenge for internal domains, you can use a local CA or self-signed cert and manage trust in your clients. ( Reddit ) This makes everything clean to access via Hostnames exclusively : https://jellyfin.lab.zn80.net https://pihole.lab.zn80.net/admin 4) Maintain Internal DNS Instead of Wildcard DNS (Optional but safer) You could be tempted to use a wildcard ( *.lab.zn80.net → 192.168.10.105 ), but that is less safe and confusing for certificate validation and service discovery. Better pattern: Pi-hole local DNS → explicit A records per hostname Pi-hole → NPM IP NPM → internal service Explicit records help: TTL management SSL certificate issuance Troubleshooting 🧠 Why This Is the Best Way ✅ DNS + Reverse Proxy are cleanly separated Pi-hole isn’t serving HTTP, so there’s no port conflict. NPM can handle 80/443 without interference. ✅ You achieve real HTTPS for internal domains Every service can have a valid certificate via NPM. ✅ Easy, scalable, and future-proof Adding a new service is trivial: Add A record in Pi-hole Add Proxy Host in NPM Done ✅ Works with VPN / local DNS clients If your devices use Pi-hole’s DNS (wired/wireless/VPN), they resolve domain names that NPM can proxy. ( Pi-hole Userspace ) 🛠 Detailed Implementation A) Change Pi-hole web interface port Edit /etc/lighttpd/lighttpd.conf : server.port = 8081 Restart: sudo systemctl restart lighttpd B) Add DNS entries in Pi-hole In Pi-hole: Local DNS → DNS Records Examples: pihole.lab.zn80.net → 192.168.10.105 jellyfin.lab.zn80.net → 192.168.10.105 C) In NPM, add Proxy Hosts For each service: Domain names: your local domain Forward hostname: actual service IP/port (Pi-hole admin UI at 8081) SSL: Request new cert (if public domain or DNS challenge available) Or use local CA / self-signed trusted cert Set common options: Block exploits: enabled Expires headers: optional Websockets: if needed 🚫 What Not to Do ❌ Don’t proxy Pi-hole DNS-port Do not try to proxy port 53 through NPM. DNS must be direct. ❌ Don’t expose Pi-hole admin UI publicly Pi-hole should only be accessible from your LAN or VPN. ❌ Don’t use wildcards unless you know certificate chain Wildcard DNS can break HTTPS if certificates aren’t matching. 📌 Final Result You Should See After setup: nslookup pihole.lab.zn80.net # → 192.168.10.105 nslookup jellyfin.lab.zn80.net # → 192.168.10.105 Browser: https://pihole.lab.zn80.net/admin # SSL https://jellyfin.lab.zn80.net # SSL Pi-hole DNS works, NPM handles web access, and everything is secure, consistent, and manageable.