{"id":17329562,"url":"https://github.com/haines/pi-hole-alpine","last_synced_at":"2025-06-11T14:12:34.093Z","repository":{"id":148065814,"uuid":"338580040","full_name":"haines/pi-hole-alpine","owner":"haines","description":"Setting up Pi-hole in Docker on diskless Alpine Linux on a Raspberry Pi","archived":false,"fork":false,"pushed_at":"2025-01-06T16:54:19.000Z","size":7,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-14T17:40:36.944Z","etag":null,"topics":["alpine-linux","docker","pihole","raspberry-pi"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/haines.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-02-13T13:24:05.000Z","updated_at":"2025-04-01T15:58:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"49dae96d-f407-4d76-9563-cdbf2119a1dd","html_url":"https://github.com/haines/pi-hole-alpine","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haines%2Fpi-hole-alpine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haines%2Fpi-hole-alpine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haines%2Fpi-hole-alpine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haines%2Fpi-hole-alpine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haines","download_url":"https://codeload.github.com/haines/pi-hole-alpine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haines%2Fpi-hole-alpine/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259280310,"owners_count":22833424,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alpine-linux","docker","pihole","raspberry-pi"],"created_at":"2024-10-15T14:48:37.893Z","updated_at":"2025-06-11T14:12:34.075Z","avatar_url":"https://github.com/haines.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Setting up Pi-hole in Docker on diskless Alpine Linux on a Raspberry Pi\n\nMy SD card is 32GB.\nI chose to partition it with\n\n- 256 MiB (FAT32) for the operating system,\n- 2 GiB (ext4) for the local backup utility and package cache, and\n- the remainder (ext4) for `/var/lib/docker`.\n\n## Prepare the SD card (on macOS)\n\nFind the device name with\n\n```console\n$ diskutil list\n```\n\nIn my case, the SD card was `/dev/disk4`.\n\nPartition the SD card with\n\n```console\n$ diskutil partitionDisk /dev/disk4 \\\n  MBR \\\n  FAT32 PI-HOLE 256MiB \\\n  FREE %noformat% R\n```\n\nDownload and extract Alpine Linux to the SD card with\n\n```console\n$ gpg --receive-keys 293ACD0907D9495A\ngpg: key 293ACD0907D9495A: public key \"Natanael Copa \u003cncopa@alpinelinux.org\u003e\" imported\n\n$ gpg --lsign-key 293ACD0907D9495A\n\n$ curl --remote-name-all https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/aarch64/alpine-rpi-3.20.0-aarch64.tar.gz{.asc,}\n\n$ gpg --verify alpine-rpi-3.20.0-aarch64.tar.gz{.asc,}\ngpg: Signature made Wed 22 May 11:33:03 2024 BST\ngpg:                using RSA key 0482D84022F52DF1C4E7CD43293ACD0907D9495A\ngpg: Good signature from \"Natanael Copa \u003cncopa@alpinelinux.org\u003e\" [full]\n\n$ tar \\\n  --extract \\\n  --file alpine-rpi-3.20.0-aarch64.tar.gz \\\n  --directory /Volumes/PI-HOLE\n```\n\nEject the SD card with\n\n```console\n$ diskutil eject /Volumes/PI-HOLE\n```\n\n## Generate an SSH key\n\nGenerate an SSH key in 1password with\n\n```console\n$ op item create --category ssh --title pihole\n```\n\nUpload the public key as a gist with\n\n```console\n$ op read \"op://personal/pihole/public key\" |\n  gh gist create --filename pihole.pub -\nhttps://gist.githubusercontent.com/...\n```\n\nTake a note of the URL for later.\n\n## Set up Alpine\n\nInsert the SD card and start the Raspberry Pi.\nLogin as `root` with no password.\n\nSet up Alpine in diskless mode with\n\n```console\n# setup-alpine\n```\n\n| Setting | Value | Notes |\n|---|---|---|\n| Keyboard layout | `gb` |\n| Keyboard layout variant | `gb` |\n| System hostname | `pihole` |\n| Network interface | `eth0` |\n| IP address | `192.168.0.2` | This depends on the router's LAN settings |\n| Netmask | `255.255.255.0` |\n| Gateway | `192.168.0.1` |\n| Manual network configuration | `n` |\n| DNS domain name | (empty) |\n| DNS nameservers | `1.1.1.1 1.0.0.1` |\n| Timezone | `UTC` |\n| HTTP/FTP proxy URL | `none` |\n| NTP client | `chrony` |\n| Mirror | `uk.alpinelinux.org` |\n| Setup a user? | `pihole` |\n| SSH server | `openssh` |\n| Unmount `/media/mmcblk0p1`? | `n` |\n| Where to store configs | `none` |\n| `apk` cache directory | `/var/cache/apk` |\n\nInstall certificate authority certificates with\n\n```console\n# apk add ca-certificates\n```\n\nEnable the `community` repository and configure the mirror with HTTPS by running\n\n```\n# cat \u003e/etc/apk/repositories \u003c\u003cEOF\n/media/mmcblk0p1/apks\nhttps://uk.alpinelinux.org/alpine/v3.20/main\nhttps://uk.alpinelinux.org/alpine/v3.20/community\nEOF\n```\n\nUpgrade any outdated packages with\n\n```console\n# apk update\n\n# apk upgrade\n```\n\nFinish partitioning the SD card with\n\n```console\n# apk add e2fsprogs parted\n\n# parted /dev/mmcblk0 mkpart primary ext4 257MiB 2305MiB\n\n# mkfs.ext4 /dev/mmcblk0p2\n\n# parted /dev/mmcblk0 mkpart primary ext4 2305MiB 100%\n\n# mkfs.ext4 /dev/mmcblk0p3\n\n# apk del e2fsprogs parted\n```\n\nCreate mount points for the writable partitions with\n\n```console\n# mkdir /media/mmcblk0p2 /var/lib/docker\n```\n\nAdd the writable partitions with\n\n```\n# cat \u003e\u003e/etc/fstab \u003c\u003cEOF\n/dev/mmcblk0p2 /media/mmcblk0p2 ext4 defaults 0 0\n/dev/mmcblk0p3 /var/lib/docker ext4 defaults 0 0\nEOF\n```\n\nMount the writable partitions with\n\n```console\n# mount -a\n```\n\nSet up the local backup utility with\n\n```console\n# setup-lbu mmcblk0p2\n```\n\nSet up the `apk` cache with\n\n```console\n# setup-apkcache /media/mmcblk0p2/cache\n```\n\nAuthorize the SSH key with\n\n```console\n# su - pihole\n\n$ mkdir ~/.ssh\n\n$ chmod a=,u=rwx ~/.ssh\n\n$ wget --output-document ~/.ssh/authorized_keys https://gist.githubusercontent.com/...\n\n$ chmod a=,u=rw ~/.ssh/authorized_keys\n\n$ exit\n```\n\nAllow `chronyd` to step the system clock with\n\n```\n# echo \"makestep 1 -1\" \u003e\u003e/etc/chrony/chrony.conf\n```\n\nInstall Docker with\n\n```console\n# apk add docker\n\n# rc-update add docker\n```\n\nEnable user namespace remapping with\n\n```console\n# echo \"pihole:65536:65536\" \u003e/etc/subgid\n\n# echo \"pihole:65536:65536\" \u003e/etc/subuid\n\n# mkdir /etc/docker\n\n# echo '{\"userns-remap\":\"pihole\"}' \u003e/etc/docker/daemon.json\n```\n\nStart Docker with\n\n```console\n# service docker start\n```\n\nCreate a file setting the Pi-hole environment variables to\n\n```\nDNSMASQ_LISTENING=all\nPIHOLE_DNS_=1.1.1.1;1.0.0.1\nWEBPASSWORD=...\n```\n\nwith\n\n```console\n# vi /etc/pihole\n\n# chmod u=rw,g=r,o= /etc/pihole\n```\n\nAdd a script to start Pi-hole with\n\n```console\n# cat \u003e/usr/local/bin/pihole \u003c\u003cEOF\ndocker run \\\n  --detach \\\n  --dns 127.0.0.1 \\\n  --dns 1.1.1.1 \\\n  --dns 1.0.0.1 \\\n  --env-file /etc/pihole \\\n  --mount type=volume,source=dnsmasq,target=/etc/dnsmasq.d \\\n  --mount type=volume,source=pihole,target=/etc/pihole \\\n  --name pihole \\\n  --publish 53:53/tcp \\\n  --publish 53:53/udp \\\n  --publish 80:80 \\\n  --pull always \\\n  --restart always \\\n  pihole/pihole:latest\nEOF\n\n# chmod +x /usr/local/bin/pihole\n\n# lbu include /usr/local/bin/pihole\n```\n\nStart Pi-hole with\n\n```console\n# pihole\n```\n\nClear the message of the day with\n\n```console\n# : \u003e/etc/motd\n```\n\nCommit configuration with\n\n```console\n# lbu commit\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaines%2Fpi-hole-alpine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaines%2Fpi-hole-alpine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaines%2Fpi-hole-alpine/lists"}