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.

Step 1 – Set secondary static IP

First, 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 that, and just this step could deserve a guide by itself. The method that I’ll describe here is the one that has worked best for me so far. Feel free to do your own research and come up with other (possibly better) ways.

Before we start, I don’t know if I need to remember you, and I think I don’t, but I will. Please make a copy of the original files before editing them. Also, be careful if doing this remotely, since we are editing the network configuration and a mistake could make you lose your connection to the Pi.

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.

Restart dhcpcd or reboot your system:

$ sudo systemctl daemon-reload
$ sudo systemctl restart networking
$ sudo systemctl restart dhcpcd

Issue 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 /etc/network/interfaces.

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

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 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 one of the IP addresses 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 lighttpd.conf.

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. How to do this, obviously, depends on which web server you pick and your specific configuration.

However, the procedure is analogous to what we did on step 2. Edit the configuration of the chosen server and bind it to your Pi’s secondary IP.

For example, on Nginx, you do it using the listen directive.

listen 10.0.0.11:80

After making the needed modifications, start the web 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

This step is necessary because it tells Pi Hole to resolve the blocked domains to that address. It’s expected to 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.


Updates:

  • 2019/03/01: Pi Hole now sources a custom configuration file for Lighttpd.
  • 2019/08/07: Better method of assigning secondary IP, taking dhcpcd in account.