Running a web server while using Pi Hole
Notice (2020-07-27): This post was written in 2018 and describes the solution I implemented a year before.
Since then, most of the web has migrated to HTTPS, making Pi Hole’s “blocked” page almost pointless. Pi Hole now mostly uses the webserver for the admin console, meaning that our requirements have relaxed quite a bit.
While implementing my 2017’s solution show still work, I consider it now overkill. My suggestion in 2020, if you want to use something like Apache or Nginx only facing your LAN, is to keep Pi Hole’s
/admindirectory on your chosen webserver and enable PHP. Then, disable or uninstall Lighttpd. The admin console will be available under
Another solution is to just change Lighttpd port, leaving it free for Apache or Nginx. But you’ll have to remember to type the port and will have two webservers running.
If you are running Pi Hole and want to deploy a web application to your Raspberry Pi, chances are that you’ll hit your head to the wall. That’s because Pi Hole installs and configures a web server (Lighttpd) for itself using port 80.
This way, Lighttpd:
- Serves the admin dashboard at
- Shows a “blocked” page whenever you bump at a blocked domain.
So what can you do?
There are many solutions to this, and, of course, which one suits you best depends on your specific situation. On this post, I’ll list some of them, their caveats, and explain what I did on my Pi.
First is the one I dislike more: buying another Raspberry Pi. Alright, that’s a no-brainer if those apps will be internet facing, but for LAN… Just why? Hell, this device can handle a lot more than Pi Hole. There’s no need to put more pressure to the environment and to our pockets.
Another solution is to bind your web server to a port other than 80. This can be fine for some situations, but in my case it doesn’t make it. My Pi serves a bunch of web applications for the LAN. Instead of forcing the users to memorize different ports, or make them go through a menu, I assign friendly domain names. This intended ease of use on my LAN makes port 80 fundamental for me.
So going forward, you could edit the Lighttpd configuration set by Pi Hole. This way, you would make Lighttpd also serve your applications, for example choosing them according to the name on the request.
This one could sure do it, but it isn’t a very clean approach. Why? You have to learn a bit of what Pi Hole expects the web server to do and not mess it up. Also, a possible change upstream will have to be merged into your configuration.
Another problem with this solution: what if you don’t want to use Lighttpd for your projects? Maybe you have a very complex Nginx or Apache setup and don’t see yourself rewriting it because of Pi Hole.
In this case, an alternative is to nuke the Lighttpd installation, install the web server of your choice and then proceed to do all the configuration – for your apps, and for Pi Hole. If you choose Nginx, there is a guide for it. However, this solution has the same caveat of having to mess with the web configuration of Pi Hole.
Alright, so what did I come with for my Pi?
I decided to take a simpler and cleaner approach. Besides being easy to setup, using it for 20 months resulted in no headaches. This is:
- set an additional IP for the Raspberry Pi
- bind Lighttpd to the original IP
- bind our app web server to the new IP
And we are done. This way you:
- Can use port 80 however you want, all for you, as if Pi Hole wasn’t installed.
- Use whatever web server you pick for your apps, configuring it as you always did.
- Barely have to touch whatever Pi Hole configured Lighttpd to do, so it works exactly as intended.
- Don’t have to perform any maintenance since Pi Hole 4.2.2 (on earlier versions you only had to do a minor edit on configuration at every update).
The caveat here is that you have to run two separate web servers. Maybe for your situation this won’t be acceptable. But in my particular setup and typical load, there’s no performance impact in any significant way.