PiHoleHQ
A stylized 3D Raspberry Pi sits beside a home, Wi-Fi router, Ethernet cable, and microSD card on a dark blue background.
getting-started

How to Set Up Pi-hole on Raspberry Pi (v6, Step by Step)

Set up Pi-hole on a Raspberry Pi under v6: prerequisites, a fixed IP, the installer, upstream choice, DHCP option 6, and the tests that prove it works.

By PiHoleHQ Editorial · ·Updated September 6, 2026 · 5 min read

Most published walkthroughs on how to set up Pi-hole on Raspberry Pi still describe version 5: lighttpd, PHP, a setupVars.conf file, and a password command that no longer exists. Version 6 folded the web server and a REST API into the pihole-FTL binary and moved configuration into one TOML file, dropping the lighttpd and PHP dependency. Follow a v5 guide on a v6 install and you will be editing files that are not there.

This is the current path, with the verification queries at the end.

What the install actually requires

The prerequisites page sets the floor at 512 MB of RAM and 2 GB of free disk, 4 GB recommended. Supported operating systems are Alpine, Armbian, Debian, CentOS Stream, Fedora, Raspberry Pi OS and Ubuntu, in actively maintained versions. FTL ships prebuilt for x86_64, i686, armv6, armv7, armv8 (aarch64) and riscv64, which covers a Pi Zero W through a Pi 5.

ServicePortProtocolRequired
DNS53TCP/UDPYes
Web interface / API80, 443TCPYes, falls back to 8080/8443
DHCPv467UDPOnly if Pi-hole runs DHCP
DHCPv6547UDPOnly if Pi-hole runs DHCP
NTP123UDPOptional

Before choosing a Raspberry Pi model or storage device, check the hardware requirements first. That guide separates Pi-hole’s minimum specifications from the device and storage choices involved in keeping a DNS host available.

Flash the OS and get a shell

Use Raspberry Pi Imager and pick Raspberry Pi OS Lite, 64-bit. A desktop on a DNS appliance is disk, RAM and attack surface you never use.

Before writing the card, open the OS customisation panel: hostname, user account, Wi-Fi credentials, locale, and SSH including public-key authentication. On a headless first boot only SSH and Raspberry Pi Connect are reachable, so a card flashed without SSH means pulling it back out. Prefer wired Ethernet.

sudo apt update && sudo apt full-upgrade -y && sudo reboot

Pin the address before you install

Pi-hole needs a static IP address, and a DHCP reservation counts. Set it on the router, keyed to the Pi’s MAC, inside the LAN subnet. On a flat 192.168.1.0/24 with a pool of .100 to .199, reserve 192.168.1.53 outside that pool. The .53 is a mnemonic, not a requirement, but it makes the address obvious in six months.

Do this first: every client is about to carry that address in its resolver config, and if it moves, name resolution breaks for the whole LAN at once.

Run the installer

curl -sSL https://install.pi-hole.net | bash

The install docs raise their own caveat, that piping to bash stops you reading the code before it runs. Two documented alternatives fetch the same script and let you read it:

wget -O basic-install.sh https://install.pi-hole.net
sudo bash basic-install.sh
git clone --depth 1 https://github.com/pi-hole/pi-hole.git Pi-hole
cd "Pi-hole/automated install/"
sudo bash basic-install.sh

The installer is a text menu covering upstream resolver, listening interface, starting blocklist and query logging. None of it is permanent; every answer becomes a config key.

Set the password and find the dashboard

pihole setpassword

Run it bare. The documented syntax also accepts pihole setpassword secretpassword, which puts the password on screen and into shell history.

pihole-FTL binds 80 for HTTP and 443 for HTTPS, reverting to 8080 if something already holds 80. The default webserver.port is "80o,443os,[::]:80o,[::]:443os", covering both address families. If the dashboard does not answer where you expect, try 8080 before blaming the install.

Configuration lives in /etc/pihole/pihole.toml, and every key is settable from the CLI:

sudo pihole-FTL --config dns.dnssec true
sudo pihole-FTL --config -h

The REST API is self-documented on the box at http://pi.hole/api/docs, matching the installed version.

Choose an upstream, or resolve recursively

Forwarding to a public resolver is the default. It is fast, and it hands one operator a log of every name your household looks up.

The alternative is recursion. The project documents unbound for it: sudo apt install unbound, config in /etc/unbound/unbound.conf.d/pi-hole.conf, listening on 5335 so it does not collide with FTL on 53. Then make loopback the only upstream:

sudo pihole-FTL --config dns.upstreams '[ "127.0.0.1#5335" ]'

The guide’s DNSSEC check is two dig queries against 127.0.0.1 port 5335, one signed and one deliberately broken: SERVFAIL expected on the broken one, NOERROR with the ad flag on the good one. If both succeed, validation is not running. The trade is slower cold lookups and owning root-hint freshness.

Point the network at it

Three documented ways to get clients using Pi-hole, worst-scaling last:

Router DHCP. Hand out the Pi-hole address as the DNS server for DHCP clients. That field is DHCP option 6, the Domain Name Server option, defined in RFC 2132 section 3.8. One change, whole network, and it survives new devices joining.

Pi-hole’s own DHCP server. dhcp.active defaults to false. Enable it only if the router will not let you change option 6, and disable the router’s DHCP first. Two DHCP servers on one broadcast domain is a race.

Per-device configuration. Fine for testing one laptop, unworkable as a policy.

Two things bite people here. dns.listeningMode defaults to LOCAL, which answers local subnets only; the allowed values are LOCAL, SINGLE, BIND, ALL and NONE. Put Pi-hole on a different VLAN from its clients and LOCAL silently drops those queries. Second, IPv6: if the router still advertises itself as a recursive DNS server in its Router Advertisements, dual-stack clients resolve around Pi-hole entirely.

What to test before you call it done

pihole status
dig @192.168.1.53 example.com +short
dig @192.168.1.53 pi.hole

Then, from a client that has renewed its lease, confirm it actually received the Pi-hole address and not the router’s:

resolvectl status          # systemd Linux
ipconfig /all              # Windows
scutil --dns               # macOS

That check is the one people skip and the one that matters. Then query a domain you can see on a blocklist: the answer should not be the site’s real address, and the log entry should be flagged as blocked. Watch the log’s client column too. If everything appears to come from one address, something between the clients and Pi-hole is forwarding DNS on their behalf and per-device visibility is gone. If blocking looks partial, work the diagnostic order for a Pi-hole that stopped blocking.

One browser-specific check: Firefox reads a NOERROR answer with A or AAAA records for the canary domain use-application-dns.net as permission to keep DNS over HTTPS on, and NXDOMAIN or SERVFAIL as a signal to turn it off, per Mozilla. It applies only to users running DoH by default.

Keeping it running

pihole -up updates Core, Web and FTL together. pihole -g rebuilds gravity from your subscribed lists and runs weekly on its own; run it by hand after adding a list.

Two realities worth naming. The query log is a timestamped, per-client record of every name every device asked for, which makes dashboard access more sensitive than its convenience suggests; broader coverage of DNS logging and router-level compromise sits with outlets such as TechSentinel. And this host is now a single point of failure for name resolution. Adding a second, non-filtering resolver to DHCP does not fix that, it defeats the filter: clients treat listed resolvers as interchangeable rather than ordered, so a share of queries take the unfiltered path. Redundancy means a second Pi-hole.

Sources

  1. Pi-hole documentation: Basic install
  2. Pi-hole: Introducing Pi-hole v6
  3. Pi-hole documentation: The pihole command
  4. Pi-hole documentation: Prerequisites
  5. Pi-hole documentation: Post-install
  6. Pi-hole documentation: FTL configuration file
  7. Pi-hole documentation: unbound as a recursive resolver
  8. Raspberry Pi documentation: Getting started
  9. RFC 2132: DHCP Options and BOOTP Vendor Extensions
  10. Mozilla: Canary domain use-application-dns.net

Related