I've been thinking of trying PiHole for a while now but after some issues with long running services on RaspberryPi and given the nature of the services it would provide, I haven't done much about it. During a recent chat with a friend who had tried PiHole he reminded me that I could run it inside a docker VM. The only problem with that is that docker and FreeBSD don't play.

However, where there is a will...

Bhyve

I've been using bhyve for a while now for the Home Assistant image. This has been running well for over a year so much of the required groundwork has been done.

Alpine Linux

After doing some reading the obvious choice was a simple, lightweight linux install and Alpine ticks this box.  bhyve has a simple way to install ISO files, so I found the current file from https://www.alpinelinux.org/downloads/ and copied the link.

$ sudo vm iso https://dl-cdn.alpinelinux.org/alpine/v3.16/releases/x86_64/alpine-standard-3.16.2-x86_64.iso

Once downloaded it's available for installation via bhyve.

$ sudo vm iso
DATASTORE           FILENAME
default             alpine-standard-3.16.2-x86_64.iso

Next step was to create the VM. The templates already included an entry for Alpine so I just used that.

$ sudo vm create -t alpine -c 2 -m 2G -s 32G pihole

Once created I needed to change from "vanilla" to "lts" for the Alpine configuration. Again, simple enough via bhyve :-)

$ sudo vm configure pihole
loader="grub"
cpu="2"
memory="2G"
network0_type="virtio-net"
network0_switch="public"
disk0_type="virtio-blk"
disk0_name="disk0.img"
grub_install0="linux /boot/vmlinuz-lts initrd=/boot/initramfs-lts alpine_dev=cdrom:iso9660 modules=loop,squashfs,sd-mod,usb-storage,sr-m
od"
grub_install1="initrd /boot/initramfs-lts"
grub_run0="linux /boot/vmlinuz-lts root=/dev/vda3 modules=ext4"
grub_run1="initrd /boot/initramfs-lts"
uuid="508b1d7e-1c04-11ed-8ddb-74d435eb6bb1"
network0_mac="58:9c:fc:07:92:98"

Finally it was time to install.

$ sudo vm install pihole alpine-standard-3.16.2-x86_64.iso

This initially threw me as it took me straight to a grub prompt, but I chose the install and then things progressed as expected, resulting in a login prompt.

The online docs for setting up Alpine via alpine-setup are easy to follow. I found the quick configuration option (alpine-setup -q) didn't do everything needed.

Docker

The next step was to install docker and docker-compose within Alpine. Once installed and rebooted,

$ sudo vm console pihole

Welcome to Alpine Linux 3.16
Kernel5 .15.59-0-lts on an x86_64 (/dev/ttyS0)

pihole login:

Once logged in, I needed to add the community repository to the APK repositories in /etc/apk/repositories, but could then install the various packages I needed. Details available here.

# vi /etc/apk/repositories
[ uncomment the community repository ]
# apk add --update docker docker-compose openrc
# service docker start
 * Caching service dependencies ...
 [ ok ]
 * Mounting cgroup filesystem ...
 [ ok ]
 * /var/log/docker.log: creating file
 * /var/log/docker.log: correcting owner
 * Starting Docker Daemon ...
 [ ok ]
# rc-update add docker boot
 * service docker added to runlevel boot

I also needed git :-)

# apk add --update git

Suitably prepared, it was time to install docker-pi-hole.

# git clone https://github.com/pi-hole/docker-pi-hole.git
loning into 'docker-pi-hole'...
remote: Enumerati ngobjects: 5366, done.
remote: Counting objects: 100% (436/436), done.
remote: Compressing objects: 100% (259/259), done.
remote: Total 5366 (delta 229), reused 341 (delta 164), pack-reused 4930
Receiving objects: 100% (5366/5366), 1.40 MiB | 4.88 MiB/s, done.
Resolving deltas: 100% (3126/3126), done.
# cd docker-pi-hole/
# cp examples/docker-compose.yml.example docker-compose.yml

I edited docker-compose.yml as outlined on the github page. Once complete,

# docker-compose up -d
984b787b496:f Pull complete
c48dab7e362c: Pull complete
3a176fad8719: Pull compelte
5cd7355bea16: Pull complete
3734d50778a6: Extracting [==================================================>]  4.937kB/4.937kB
3734d50778a6: Pull complete
Digest: sha256:f7624f452b7a6320405b6ff00a9ed253d99fd33a22abced1954633ceb5bae24e
Status: Downloaded newer image for pihole/pihole:latest
Creating pihole ... done

Apparently that was all I needed :-)

# docker images
REPOSITORY      TAG       MIAGE ID       CREATED       SIZE
pihole/pihole   latest    2b580d272b6c   5 weeks ago   303MB

Tailscale

I've been using the awesome tailscale to connect remotely so I installed and connected Alpine.

# apk add tailscale
# service tailscale start
* Caching service dependencies ...
 [ ok ]
 * /var/log/tailscaled.log: creating file
 * Starting tailscaled ...
 [ ok]
# tailscale up

To authenticate, visit:

	https://login.tailscale.com/a/xxxyyyzzz

Success.

# tailscale ip
100.xxx.yyy.zzz

Pointing my web browser at the tailscale IP address gave me access to a running instance of PiHole :-)

To be honest I'm stunned at how simple it was to install and how effortlessly things have worked.

I still find it awkward to leave the bhyve console, but with experience that should become simpler. Hints on how to do this welcome :-)

Next time...

Having PiHole installed and running, now I need to reconfigure the network to use it and deal with the chaos it will no doubt wreak :-)