Web server and Pi Hole - a how-to
On the previous post, we talked about how I set up a web server alongside Pi Hole. Now, I will guide you step by step on how to do it on Raspbian Stretch.
A word of caution. I think I don’t need to remember you, but I will: please make a copy of the configuration files before editing. Also, be careful if doing this remotely, since we are changing the network configuration and a mistake could make you lose your connection to the Pi.
Step 1 – Set a secondary static IP
In this first step, we’ll configure your Pi to have two static IP addresses, one for Pi Hole and other to be used by your web apps.
There are many ways to achieve it, and just this step could deserve a guide by itself. The method I describe here has worked best to me so far. Feel free to do your own research and come up with other (possibly better) ways.
Primary static IP
Let’s make sure
dhcpcd is instructed to use a static IP. Your
/etc/dhcpcd.conf should have something similar to this:
# /etc/dhcpcd.conf ... interface wlan0 static ip_address=10.0.0.10/24 static routers=10.0.0.1 static domain_name_servers=127.0.0.1
Replace the values on each line for the appropriate ones in your system. The IP in this example is
10.0.0.10. Be sure to pick an address no other device is using on your network.
The interface being configured is
wlan0. If your Pi is connected by Ethernet, change it for
eth0. We also set the DNS for
127.0.0.1, so the Pi uses the Pi Hole to resolve the names he needs. The gateway and the netmask should be set accordingly to your network.
dhcpcd or reboot your system:
$ sudo systemctl daemon-reload
$ sudo systemctl restart networking
$ sudo systemctl restart dhcpcd
ip a and check if the Pi got your chosen IP.
Secondary static IP
Now let’s set the secondary IP. In the current times, this ideally should also be done on
dhcpcd.conf. However, making it work properly has proven harder than it should.
My current approach is to bring up the second IP through
Place a file under
/etc/network/interfaces.d, and name it for example
secondary_ip. Add the following lines, replacing the values with the appropriate ones:
# /etc/network/interfaces.d/secondary_ip auto wlan0 iface wlan0 inet static address 10.0.0.11 netmask 255.255.255.0 dns-nameservers 127.0.0.1
In this example, I pick
10.0.0.11 as the secondary IP.
Have you done the proper configuration, restart your network or reboot. Your Pi should now have two static IPs. Let’s check it.
$ ip a
If all went well, you’ll see both IPs in two lines starting with
inet. For our example:
... inet 10.0.0.10/24 brd 192.168.0.255 scope global wlan0 valid_lft forever preferred_lft forever inet 10.0.0.11/24 brd 192.168.0.255 scope global secondary wlan0 valid_lft forever preferred_lft forever ...
Step 2 - Bind Lighttpd to the primary IP
Now we’re going to make Lighttpd bind only to the primary address. This will leave port 80 free for our webserver in the other address. This step is much more straight-forward.
Until recently, we achieve that editing
/etc/lighttpd/lighttpd.conf. This had the inconvenience that whenever Pi Hole updated, the file would be overwritten and all the changes lost. So every month or so, we would have to revert the relevant lines.
However, since Pi Hole 4.2.2 that problem is gone. Now, the Lighttpd config done by Pi Hole sources a separate file, allowing us to permanently store our modifications in it.
This file is
/etc/lighttpd/external.conf. Add this line to it, replacing
10.0.0.10 by the primary IP address you just set:
server.bind = "10.0.0.10"
If for whatever reason you are using an older version of Pi Hole, simply add that line to
Let’s restart Lighttpd:
$ sudo systemctl restart lighttpd
Now the Pi Hole admin console should only be available on your primary IP.
Step 3 - Bind your web server to the secondary IP
Finally, we need to make your web server bind only to the secondary IP. The procedure is analogous to what we did on step 2: edit the configuration of your server, binding it to your Pi’s secondary IP.
The specifics on how to do this depend on which web server you pick and your configuration.
For example, if you are using Nginx, set the
listen directive on your site configuration:
# /etc/nginx/sites-available/default # (or whatever the path for your site configuration) ... listen 10.0.0.11:80 ...
Please refer to the documentation of your web server for details.
After making this change, start the server and everything should work as we wanted.
Step 4 - Install Pi Hole or reconfigure it
If you haven’t installed Pi Hole yet, do it now, pointing it to the primary IP.
Alternatively, if Pi Hole is already installed, reconfigure it to make sure it points to that address. Run
pihole -r and select “Reconfigure”.
This step is necessary because it tells Pi Hole to resolve the blocked domains to that address. It expects Lighttpd to be there to serve the “Pi Hole blocked” page.
Also notice that this guide placed Pi Hole and Lighttpd in the primary IP and your webserver in the secondary, but the opposite is obviously also possible. The key is that Pi Hole and Lighttpd should be configured to the same address.
As a side note, the DNS server binds to both IPs and we’ll not touch it. We are only concerned about port 80, so this fact doesn’t bring any issues and is irrelevant for our goals.
Enjoy your webserver and Pi Hole together
Done. You should now be able to run Pi Hole and a webserver simultaneously and without issues on your Pi.