How to Set up PiHole with Docker on your Home Network (Ft: Traefik reverse proxy)
[WIP]
If you have seen the price Raspberry pi’s recently, with the state of the world right now along with the chip shortage you might be thinking “I can’t afford a Raspberry Pi”. Well, I have good news for you, you can run PiHole on a Docker container on your home network. This is a great way to get started with PiHole without having to spend a lot of money on a Raspberry Pi.
But what if you don’t want to spend the money on a Raspberry Pi, or you don’t have a spare one lying around? Well, you can use Docker to run PiHole on your home network.
I have picked up a thinclient off ebay 4gb RAM, 16gb storage for arount $50. The price of these bad boys is ballooning recently, but they are still significantlu cheaper than a pi at the moment ($250-400 atm for some reason). It had embedded windows installed but after some playing around in the bios I was able to get it to boot from a USB drive. I installed Ubuntu Server 20.04 on it and it has been running great ever since. I have a few other projects running on it as well, but that is a story for another day.
I’m going to hand this over to copilot to give you a run down of docker and pihole. If you want to skip to the installation, you can find it here
What is PiHole?
PiHole is a DNS sinkhole that protects your devices from unwanted content, without installing any client-side software. It is a great way to block ads and trackers on your network. It also comes with a nice web interface that allows you to see what devices are connected to your network, and how many DNS queries they have made. You can also see what domains and IPs have been blocked by PiHole.
What is Docker?
Docker is a containerization platform. It allows you to run applications in isolated containers. It is a great way to run applications that require a lot of dependencies, or that are difficult to install. It also allows you to run applications on different operating systems. For example, you can run a Windows application on a Linux machine, or a Linux application on a Windows machine.
Why use Docker?
Docker allows you to run applications on your home network without having to install them on your machine. For example, if you wanted to run a Minecraft server, you would have to install Java on your machine, and then install Minecraft. You would also have to configure the server, and open ports on your router. If you wanted to run a Minecraft server on your home network, you would have to install Java on your machine, and then install Minecraft. You would also have to configure the server, and open ports on your router.
How to use Docker
To use Docker, you will need to install Docker on your machine. You can find instructions for installing Docker on your machine here. You will also need to install Docker Compose. You can find instructions for installing Docker Compose on your machine here.
Installation
With Traefik
I have been using traefik as a reverse proxy for everything recently, this post will assume you have managed to set up a traefik instance on your network and have docker network set up.
If you haven’t set up traefik yet, you can use this basic (yet fully functional) docker-compose file to get started.
I like to keep my traefik config in a seperate directory and treat the compose project as a seprete entity. This means it’s allways running and any other docker-compose files I have can use the traefik network.
Let’s assume you are in the root directory for the project:
mkdir traefik
cd traefik
vim docker-compose.yml
and then paste the following into the file:
version: "3.3"
services:
traefik:
image: "traefik:v2.4"
container_name: "traefik"
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "443:443"
- "52:52" # only needed if you want to use DNS over HTTPS
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- lan
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`traefik.local`)"
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.routers.api.entrypoints=web"
networks:
lan:
external: true
```
Now that we have traefik set up, we can move on to setting up PiHole.
### PiHole
We are going to use the [PiHole docker image](https://hub.docker.com/r/pihole/pihole) from Docker Hub. We will also use the [Traefik docker image](https://hub.docker.com/_/traefik) from Docker Hub.
Let's assume you are in the root directory for the project:
```bash
mkdir pihole
cd pihole
vim docker-compose.yml
and then paste the following into the file:
version: "3.3"
services:
pihole:
image: "pihole/pihole:latest"
container_name: "pihole"
environment:
- TZ="Australia/Melbourne"
- WEBPASSWORD="yourpassword"
- DNS1=8.8.8.8
Copy/paste Tl;dr
Lifted from here
mkdir traefik-pihole
cd traefik-pihole
vim docker-compose.yml
version: '3'
services:
traefik:
container_name: traefik
domainname: homedomain.lan
image: traefik
restart: unless-stopped
# Note I opt to whitelist certain apps for exposure to traefik instead of auto discovery
# use `--docker.exposedbydefault=true` if you don't want to have to do this
command: "--web --docker --docker.domain=homedomain.lan --docker.exposedbydefault=false --logLevel=DEBUG"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /dev/null:/traefik.toml
networks:
- default
- discovery
dns:
- 192.168.1.50
- 192.168.1.1
pihole:
container_name: pihole
domainname: homedomain.lan
image: diginc/pi-hole:debian
ports:
- '0.0.0.0:53:53/tcp'
- '0.0.0.0:53:53/udp'
- '0.0.0.0:67:67/udp'
- '0.0.0.0:8053:80/tcp'
volumes:
# run `touch ./pihole.log` first unless you like errors
# - ./pihole.log:/var/log/pihole.log
- ./etc-pihole/:/etc/pihole/
- ./etc-dnsmasqd/:/etc/dnsmasq.d/
environment:
ServerIP: 192.168.1.50
PROXY_LOCATION: pihole
VIRTUAL_HOST: pihole.homedomain.lan
VIRTUAL_PORT: 80
TZ: 'America/Chicago'
# WEBPASSWORD:
restart: unless-stopped
labels:
# required when using --docker.exposedbydefault=false
- "traefik.enable=true"
# https://www.techjunktrunk.com/docker/2017/11/03/traefik-default-server-catch-all/
- "traefik.frontend.rule=HostRegexp:pihole.homedomain.lan,{catchall:.*}"
- "traefik.frontend.priority=1"
- "traefik.backend=pihole"
- "traefik.port=80"
networks:
# Discovery is manually created to avoid forcing any order of docker-compose stack creation (`docker network create discovery`)
# allows other compose files to be seen by proxy
# Not required if you aren't using multiple docker-compose files...
discovery:
external: true
Comments....