Skip to content

Setting up Pi-hole in Docker on diskless Alpine Linux on a Raspberry Pi

Notifications You must be signed in to change notification settings

haines/pi-hole-alpine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 

Repository files navigation

Setting up Pi-hole in Docker on diskless Alpine Linux on a Raspberry Pi

My SD card is 32GB. I chose to partition it with

  • 256 MiB (FAT32) for the operating system,
  • 2 GiB (ext4) for the local backup utility and package cache, and
  • the remainder (ext4) for /var/lib/docker.

Prepare the SD card (on macOS)

Find the device name with

$ diskutil list

In my case, the SD card was /dev/disk4.

Partition the SD card with

$ diskutil partitionDisk /dev/disk4 \
  MBR \
  FAT32 PI-HOLE 256MiB \
  FREE %noformat% R

Download and extract Alpine Linux to the SD card with

$ gpg --receive-keys 293ACD0907D9495A
gpg: key 293ACD0907D9495A: public key "Natanael Copa <[email protected]>" imported

$ gpg --lsign-key 293ACD0907D9495A

$ curl --remote-name-all https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/aarch64/alpine-rpi-3.20.0-aarch64.tar.gz{.asc,}

$ gpg --verify alpine-rpi-3.20.0-aarch64.tar.gz{.asc,}
gpg: Signature made Wed 22 May 11:33:03 2024 BST
gpg:                using RSA key 0482D84022F52DF1C4E7CD43293ACD0907D9495A
gpg: Good signature from "Natanael Copa <[email protected]>" [full]

$ tar \
  --extract \
  --file alpine-rpi-3.20.0-aarch64.tar.gz \
  --directory /Volumes/PI-HOLE

Eject the SD card with

$ diskutil eject /Volumes/PI-HOLE

Generate an SSH key

Generate an SSH key in 1password with

$ op item create --category ssh --title pihole

Upload the public key as a gist with

$ op read "op://personal/pihole/public key" |
  gh gist create --filename pihole.pub -
https://gist.githubusercontent.com/...

Take a note of the URL for later.

Set up Alpine

Insert the SD card and start the Raspberry Pi. Login as root with no password.

Set up Alpine in diskless mode with

# setup-alpine
Setting Value Notes
Keyboard layout gb
Keyboard layout variant gb
System hostname pihole
Network interface eth0
IP address 192.168.0.2 This depends on the router's LAN settings
Netmask 255.255.255.0
Gateway 192.168.0.1
Manual network configuration n
DNS domain name (empty)
DNS nameservers 1.1.1.1 1.0.0.1
Timezone UTC
HTTP/FTP proxy URL none
NTP client chrony
Mirror uk.alpinelinux.org
Setup a user? pihole
SSH server openssh
Unmount /media/mmcblk0p1? n
Where to store configs none
apk cache directory /var/cache/apk

Install certificate authority certificates with

# apk add ca-certificates

Enable the community repository and configure the mirror with HTTPS by running

# cat >/etc/apk/repositories <<EOF
/media/mmcblk0p1/apks
https://uk.alpinelinux.org/alpine/v3.20/main
https://uk.alpinelinux.org/alpine/v3.20/community
EOF

Upgrade any outdated packages with

# apk update

# apk upgrade

Finish partitioning the SD card with

# apk add e2fsprogs parted

# parted /dev/mmcblk0 mkpart primary ext4 257MiB 2305MiB

# mkfs.ext4 /dev/mmcblk0p2

# parted /dev/mmcblk0 mkpart primary ext4 2305MiB 100%

# mkfs.ext4 /dev/mmcblk0p3

# apk del e2fsprogs parted

Create mount points for the writable partitions with

# mkdir /media/mmcblk0p2 /var/lib/docker

Add the writable partitions with

# cat >>/etc/fstab <<EOF
/dev/mmcblk0p2 /media/mmcblk0p2 ext4 defaults 0 0
/dev/mmcblk0p3 /var/lib/docker ext4 defaults 0 0
EOF

Mount the writable partitions with

# mount -a

Set up the local backup utility with

# setup-lbu mmcblk0p2

Set up the apk cache with

# setup-apkcache /media/mmcblk0p2/cache

Authorize the SSH key with

# su - pihole

$ mkdir ~/.ssh

$ chmod a=,u=rwx ~/.ssh

$ wget --output-document ~/.ssh/authorized_keys https://gist.githubusercontent.com/...

$ chmod a=,u=rw ~/.ssh/authorized_keys

$ exit

Allow chronyd to step the system clock with

# echo "makestep 1 -1" >>/etc/chrony/chrony.conf

Install Docker with

# apk add docker

# rc-update add docker

Enable user namespace remapping with

# echo "pihole:65536:65536" >/etc/subgid

# echo "pihole:65536:65536" >/etc/subuid

# mkdir /etc/docker

# echo '{"userns-remap":"pihole"}' >/etc/docker/daemon.json

Start Docker with

# service docker start

Create a file setting the Pi-hole environment variables to

DNSMASQ_LISTENING=all
PIHOLE_DNS_=1.1.1.1;1.0.0.1
WEBPASSWORD=...

with

# vi /etc/pihole

# chmod u=rw,g=r,o= /etc/pihole

Add a script to start Pi-hole with

# cat >/usr/local/bin/pihole <<EOF
docker run \
  --detach \
  --dns 127.0.0.1 \
  --dns 1.1.1.1 \
  --dns 1.0.0.1 \
  --env-file /etc/pihole \
  --mount type=volume,source=dnsmasq,target=/etc/dnsmasq.d \
  --mount type=volume,source=pihole,target=/etc/pihole \
  --name pihole \
  --publish 53:53/tcp \
  --publish 53:53/udp \
  --publish 80:80 \
  --pull always \
  --restart always \
  pihole/pihole:latest
EOF

# chmod +x /usr/local/bin/pihole

# lbu include /usr/local/bin/pihole

Start Pi-hole with

# pihole

Clear the message of the day with

# : >/etc/motd

Commit configuration with

# lbu commit

About

Setting up Pi-hole in Docker on diskless Alpine Linux on a Raspberry Pi

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published