DEV Community

Cover image for Pi-hole Setup Guide: Block Ads on Your Laptop, Phone and PC
Anass Assim
Anass Assim

Posted on

Pi-hole Setup Guide: Block Ads on Your Laptop, Phone and PC

A complete, beginner-friendly guide to running Pi-hole with Docker, connecting your devices to it, testing that it works, fixing common problems, and moving it to a Raspberry Pi later.

Pi-hole is a network-wide ad and tracker blocker. It acts as your DNS server and refuses to resolve the domains that serve ads, so blocking works on every device that uses it, with nothing to install on those devices.


Table of Contents

  1. How it works
  2. What you need
  3. Quick start
  4. Part 1: Install Pi-hole with Docker
  5. Part 2: Open the dashboard and verify
  6. Part 3: Find the Pi-hole IP address
  7. Part 4: Connect your devices
  8. Part 5: Test that it works
  9. Troubleshooting
  10. Daily use and maintenance
  11. Moving to a Raspberry Pi
  12. Blocking ads outside your home
  13. Security notes
  14. Limitations
  15. FAQ
  16. Uninstall / undo everything
  17. Useful links

How it works

Every time a device opens a website, it first asks a DNS server to turn the name (like example.com) into an IP address.

Without Pi-hole:   Device  ->  Router DNS / ISP DNS  ->  ad domains resolve normally

With Pi-hole:      Device  ->  Pi-hole  ->  ad domain?  YES -> answers 0.0.0.0 (blocked)
                                                         NO  -> forwards to upstream DNS
Enter fullscreen mode Exit fullscreen mode

Because blocking happens at the DNS level:

  • It works on phones, laptops, smart TVs and any other device that uses Pi-hole as its DNS server.
  • Nothing is installed on those devices.
  • It blocks domains, not individual ads. See Limitations.

What you need

Item Notes
A computer to run Pi-hole Laptop for testing, or a Raspberry Pi / mini PC / old PC for permanent use. It must stay on for blocking to work.
Docker Docker Desktop on Windows and macOS, Docker Engine on Linux.
A home network All devices on the same Wi-Fi / router.
Router access (optional) Only needed to cover every device automatically (see Moving to a Raspberry Pi).

Quick start

For people in a hurry. Details are in the parts below.

# 1. Start Pi-hole (one line)
docker run -d --name pihole -p 53:53/tcp -p 53:53/udp -p 8080:80/tcp -e FTLCONF_webserver_api_password=change-me -e FTLCONF_dns_listeningMode=all -v pihole:/etc/pihole --restart unless-stopped pihole/pihole:latest

# 2. Open the dashboard
#    http://localhost:8080/admin

# 3. Find the host IP (example: 192.168.1.70), then set it as the
#    DNS server on every device you want to protect.

# 4. Test
dig @<PIHOLE_IP> doubleclick.net      # should return 0.0.0.0
Enter fullscreen mode Exit fullscreen mode

Part 1: Install Pi-hole with Docker

1.1 Install Docker

Check that Docker works:

docker --version
docker run --rm hello-world
Enter fullscreen mode Exit fullscreen mode

On Linux you may need sudo before docker commands, or add your user to the docker group.

1.2 Start Pi-hole

Option A: one command (simplest)

Run it as one line. Replace change-me with your own password:

docker run -d --name pihole -p 53:53/tcp -p 53:53/udp -p 8080:80/tcp -e FTLCONF_webserver_api_password=change-me -e FTLCONF_dns_listeningMode=all -v pihole:/etc/pihole --restart unless-stopped pihole/pihole:latest
Enter fullscreen mode Exit fullscreen mode

What each part does:

Part Meaning
-d Run in the background
--name pihole Name of the container
-p 53:53/tcp -p 53:53/udp DNS port (needed so other devices can reach Pi-hole)
-p 8080:80/tcp Web dashboard on port 8080 (avoids conflicts with other web servers)
FTLCONF_webserver_api_password Dashboard password
FTLCONF_dns_listeningMode=all Lets Pi-hole answer devices on your network when running in Docker's default bridge mode
-v pihole:/etc/pihole Saves settings and lists in a Docker volume so they survive updates
--restart unless-stopped Starts Pi-hole again after a reboot

Option B: Docker Compose (recommended for a permanent setup)

Create a file named docker-compose.yml:

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8080:80/tcp"
    environment:
      TZ: "Etc/UTC"                          # change to your timezone, e.g. Europe/Paris
      FTLCONF_webserver_api_password: "change-me"
      FTLCONF_dns_listeningMode: "all"
    volumes:
      - "./etc-pihole:/etc/pihole"
    restart: unless-stopped
Enter fullscreen mode Exit fullscreen mode

Start it:

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

1.3 Check that it is running

docker ps
Enter fullscreen mode Exit fullscreen mode

You should see a container named pihole with status Up ... (healthy) and ports 53 and 8080 listed.

1.4 Linux: "port 53 already in use"

On some Linux systems (notably Ubuntu), systemd-resolved already listens on port 53. If Docker fails to start with an error about port 53:

sudo mkdir -p /etc/systemd/resolved.conf.d
printf "[Resolve]\nDNSStubListener=no\n" | sudo tee /etc/systemd/resolved.conf.d/pihole.conf
sudo systemctl restart systemd-resolved
Enter fullscreen mode Exit fullscreen mode

Then start the Pi-hole container again. (Debian with NetworkManager usually does not have this problem.)


Part 2: Open the dashboard and verify

  1. Open a browser on the same computer and go to:
   http://localhost:8080/admin
Enter fullscreen mode Exit fullscreen mode
  1. Log in with the password you chose.
  2. You should see the dashboard with Status: Active.

At this point the counters will show 0 queries. That is normal: no device is using Pi-hole yet.

Check that blocking works by asking Pi-hole directly. Replace <PIHOLE_IP> with the IP address from Part 3 (or use 127.0.0.1 on the Pi-hole computer itself):

dig @<PIHOLE_IP> doubleclick.net
Enter fullscreen mode Exit fullscreen mode

The answer section should contain 0.0.0.0. This means the domain is blocked.

On Windows, use nslookup:

nslookup doubleclick.net <PIHOLE_IP>
Enter fullscreen mode Exit fullscreen mode

If you get the 0.0.0.0 answer, Pi-hole itself works. The rest of this guide is about making your devices actually use it.


Part 3: Find the Pi-hole IP address

Devices need the local IP address of the computer running Pi-hole. In this guide it is written as <PIHOLE_IP> (for example 192.168.1.70).

System Command Look for
Windows ipconfig IPv4 Address (Wi-Fi or Ethernet adapter)
macOS ipconfig getifaddr en0 The address printed (use en1 if en0 is empty)
Linux ip a inet 192.168.x.x on your Wi-Fi or Ethernet interface

Important: home IP addresses usually change over time (DHCP). If the IP changes, devices pointing to the old one lose DNS. Give the Pi-hole computer a fixed IP with a DHCP reservation in your router settings (look for "DHCP reservation", "Address reservation" or "Static lease").


Part 4: Connect your devices

Two approaches:

Approach Covers Effort
A. Per device (this part) Only the devices you configure Good for testing
B. On the router Every device on your network See Moving to a Raspberry Pi

Make sure each device is on the same Wi-Fi as the Pi-hole computer.

4.1 The Pi-hole computer itself (Linux with NetworkManager)

Show the active connections:

nmcli connection show --active
Enter fullscreen mode Exit fullscreen mode

Set the DNS (replace YOUR_WIFI_NAME with the connection name):

sudo nmcli connection modify "YOUR_WIFI_NAME" ipv4.ignore-auto-dns yes ipv4.dns <PIHOLE_IP> ipv6.ignore-auto-dns yes
sudo nmcli connection up "YOUR_WIFI_NAME"
Enter fullscreen mode Exit fullscreen mode

Verify:

cat /etc/resolv.conf
dig doubleclick.net
Enter fullscreen mode Exit fullscreen mode

resolv.conf should show nameserver <PIHOLE_IP> and dig should report SERVER: <PIHOLE_IP>#53 and answer 0.0.0.0.

If you skip this step, the computer running Pi-hole keeps using the router's DNS and its own browser will not be protected, even though Pi-hole works for other devices.

4.2 Windows

  1. Settings -> Network & internet -> Wi-Fi -> click your network
  2. DNS server assignment -> Edit
  3. Choose Manual, switch IPv4 on
  4. Preferred DNS: <PIHOLE_IP> (leave the alternate empty)
  5. Save, then open a terminal and run:
ipconfig /flushdns
Enter fullscreen mode Exit fullscreen mode

If Windows Firewall asks about Docker on the Pi-hole computer, allow it on private networks.

4.3 macOS

  1. System Settings -> Network -> Wi-Fi -> Details...
  2. DNS tab -> click + and add <PIHOLE_IP>
  3. Remove other DNS servers from the list
  4. OK

4.4 Android

  1. Settings -> Network & internet -> Wi-Fi
  2. Long-press your network -> Modify network -> Advanced options
  3. IP settings: Static
  4. Keep the existing IP address, gateway and prefix length the same
  5. DNS 1: <PIHOLE_IP> and clear DNS 2
  6. Save

Then turn off Private DNS, which would bypass Pi-hole:

Settings -> Network & internet -> Private DNS -> Off

(The exact menu names vary by phone brand.)

Setting a static IP on Android can be fiddly. If you prefer, set the DNS on the router instead (see Moving to a Raspberry Pi).

4.5 iPhone / iPad

  1. Settings -> Wi-Fi -> tap the (i) next to your network
  2. Configure DNS -> Manual
  3. Delete the existing servers and Add Server: <PIHOLE_IP>
  4. Save
  5. On the same screen, turn off Limit IP Address Tracking (iCloud Private Relay) for this network. Private Relay bypasses your DNS.

4.6 Disable browser "secure DNS" (important)

Browsers can send DNS through their own encrypted resolver, skipping Pi-hole completely.

  • Firefox: Settings -> Privacy & Security -> DNS over HTTPS -> Off
  • Chrome / Edge / Brave: Settings -> Privacy and security -> Security -> turn off Use secure DNS

Also turn off any VPN while testing, because VPNs usually use their own DNS.

4.7 IPv6 note

If your router also advertises an IPv6 DNS server, some devices will use it instead of Pi-hole. If you see ads still loading or devices missing from the Query Log, try disabling IPv6 on that device's Wi-Fi connection while testing, or ignore automatic IPv6 DNS as in the Linux command above.


Part 5: Test that it works

5.1 Check the dashboard

Open http://<PIHOLE_IP>:8080/admin (or http://localhost:8080/admin on the Pi-hole computer) and browse some websites on your devices.

You should see:

  • Total Queries going up
  • Queries Blocked greater than 0 (typically 10-30% on a normal day)
  • Active clients increasing as you connect more devices

5.2 Check which devices are connected

Dashboard -> Query Log. The client column shows the IP of each device that is using Pi-hole:

  • Your phone and PC appear as 192.168.x.x
  • The Pi-hole computer's own queries may appear as 172.17.0.1. That is Docker's internal address and is normal.

5.3 See what was blocked

Click List blocked queries on the dashboard to see exactly which domains were stopped.

5.4 Test from each device

From a PC (Windows, macOS, Linux):

nslookup doubleclick.net <PIHOLE_IP>
Enter fullscreen mode Exit fullscreen mode

The answer should be 0.0.0.0.

From a phone: open this in the phone browser while on the same Wi-Fi:

http://<PIHOLE_IP>:8080/admin
Enter fullscreen mode Exit fullscreen mode

If the dashboard opens, the phone can reach Pi-hole, so any remaining problem is the phone's DNS setting.


Troubleshooting

Quick diagnosis

Symptom Likely cause Fix
Dashboard shows 0 queries No device uses Pi-hole yet Set DNS on the devices (Part 4), including the Pi-hole computer itself
dig shows SERVER: 192.168.1.1 (your router) The device still uses the router's DNS Redo the DNS setting for that device and reconnect Wi-Fi
dig @<PIHOLE_IP> doubleclick.net does not return 0.0.0.0 Pi-hole problem Check docker ps and docker logs pihole
No internet after changing DNS Pi-hole unreachable (Docker stopped, computer asleep, firewall, wrong IP) Set DNS back to automatic, then check the items in this table
Phone or PC cannot open http://<PIHOLE_IP>:8080/admin Router isolation, different network, or firewall See Router isolation and Firewall
Dashboard works but a device is missing in Query Log Device bypasses your DNS Disable Private DNS / Private Relay / browser secure DNS / VPN / IPv6 DNS
It worked, then stopped The Pi-hole computer's IP changed or it went to sleep Check the IP again, set a DHCP reservation, disable sleep
Some ads still show Normal DNS-level limitation See Limitations
Error: port 53 already in use Another service uses port 53 See 1.4

Router isolation

If devices cannot reach the Pi-hole computer at all (the dashboard does not open from the phone or PC):

  1. Log in to your router (often http://192.168.1.1).
  2. Look for AP Isolation, Client Isolation or Guest network and turn isolation off.
  3. Make sure all devices are on the same Wi-Fi network (not a guest network, not mobile data).
  4. Reconnect the devices and test again.

Firewall

On the Pi-hole computer, make sure ports 53 (TCP and UDP) and 8080 (TCP) are reachable from your local network.

  • Windows: allow Docker on private networks when prompted.
  • Linux with ufw: check with sudo ufw status. If it says inactive, it is not blocking anything and you can leave it off. If you use it, the correct commands are:
  sudo ufw allow from 192.168.1.0/24 to any port 53
  sudo ufw allow from 192.168.1.0/24 to any port 8080 proto tcp
Enter fullscreen mode Exit fullscreen mode

Replace 192.168.1.0/24 with your own network range.

See whether DNS packets reach the computer (advanced)

sudo apt install tcpdump
sudo tcpdump -ni <INTERFACE> udp port 53 and host <DEVICE_IP>
Enter fullscreen mode Exit fullscreen mode

Browse on the device:

  • Packets appear: the network path works, so check the Query Log.
  • Nothing appears: the device is not sending DNS to Pi-hole. Check its DNS settings, Private DNS / Private Relay, VPN, or router isolation.

Useful diagnostic commands

docker ps                       # is the container running and healthy?
docker logs pihole              # Pi-hole logs
docker restart pihole           # restart Pi-hole
cat /etc/resolv.conf            # Linux: which DNS does this computer use?
dig doubleclick.net             # which server answered, and is it 0.0.0.0?
Enter fullscreen mode Exit fullscreen mode

Daily use and maintenance

Update Pi-hole (Docker)

Settings are stored in the volume, so updating does not lose them.

docker pull pihole/pihole:latest
docker rm -f pihole
# run the same "docker run ..." command from Part 1 again
Enter fullscreen mode Exit fullscreen mode

With Docker Compose:

docker compose pull
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Change the dashboard password

docker exec -it pihole pihole setpassword
Enter fullscreen mode Exit fullscreen mode

(On a Raspberry Pi installed without Docker: sudo pihole setpassword.)

Update the blocklists

Dashboard -> Tools -> Update Gravity, or:

docker exec pihole pihole -g
Enter fullscreen mode Exit fullscreen mode

Add more blocklists

  1. Dashboard -> Lists
  2. Paste the list URL into the address field and click Add
  3. Run Update Gravity (Tools menu)

Start with a few well-maintained lists, for example from The Firebog (the green "tick" lists are the safest). Adding too many aggressive lists breaks websites.

A website is broken (allow a domain)

  1. Dashboard -> Query Log and find the blocked domain
  2. Add it to the allow list, or go to Domains and add it as an allowed domain
  3. Reload the site

You can also pause blocking temporarily with Disable Blocking in the menu.

Back up your settings

Dashboard -> Settings -> Teleporter -> Export. Keep the file somewhere safe. You can import it on a new Pi-hole (for example after moving to a Raspberry Pi).

Common commands

docker stop pihole              # stop
docker start pihole             # start
docker restart pihole           # restart
docker logs -f pihole           # follow the logs
Enter fullscreen mode Exit fullscreen mode

Moving to a Raspberry Pi

A laptop only blocks ads while it is on. A Raspberry Pi (or any always-on device) is better for permanent use.

1. Prepare the Raspberry Pi

  1. Install Raspberry Pi OS Lite with the Raspberry Pi Imager (enable SSH in the settings).
  2. Connect it to your router with an Ethernet cable if possible.
  3. In your router, create a DHCP reservation so the Pi always gets the same IP (for example 192.168.1.50).

2. Install Pi-hole

Either use the same Docker commands as in this guide (install Docker first), or use the official installer:

curl -sSL https://install.pi-hole.net | bash
Enter fullscreen mode Exit fullscreen mode

Follow the wizard:

  • Pick an upstream DNS provider (Cloudflare, Quad9, etc.)
  • Keep the default blocklist
  • Keep the web admin interface enabled

Set the dashboard password:

sudo pihole setpassword
Enter fullscreen mode Exit fullscreen mode

The dashboard is then at http://<PI_IP>/admin.

3. Cover every device: set DNS on the router

  1. Log in to your router.
  2. Find the DHCP or LAN settings with a DNS server field.
  3. Set the primary DNS to the Pi's IP (for example 192.168.1.50).
  4. Leave the secondary DNS empty. If you add a public DNS as a backup, devices may use it and skip Pi-hole.
  5. Save, then reconnect your devices (turn Wi-Fi off and on).

Every device that gets its settings automatically from the router now uses Pi-hole, and you can set your phone and PC back to Automatic DNS.

If your router does not allow changing DNS, you can use Pi-hole's built-in DHCP server instead: disable DHCP on the router and enable it in Pi-hole (Settings -> DHCP). Only do this if you understand the change, because two DHCP servers on one network cause problems.

4. Import your settings (optional)

Export a Teleporter backup from the old Pi-hole and import it on the new one: Settings -> Teleporter.


Blocking ads outside your home

When your phone uses mobile data or another Wi-Fi, it does not talk to the Pi-hole at home. To keep the protection, connect to your home network through a VPN:

  • Tailscale is the easiest option:
    1. Install Tailscale on the Pi-hole computer and on your phone.
    2. In the Tailscale admin console go to DNS and add the Pi-hole's Tailscale IP as a custom nameserver.
    3. Enable Override local DNS.
    4. Make sure Pi-hole answers Tailscale clients (in Docker you already set FTLCONF_dns_listeningMode=all; on a bare-metal install set Settings -> DNS -> Permit all origins).
  • WireGuard (for example with PiVPN) is a self-hosted alternative.

Do not make Pi-hole reachable directly from the internet (see below).


Security notes

  • Never port-forward port 53 (or the dashboard) to the internet. An open DNS server can be abused in attacks. Use a VPN instead.
  • Use a strong dashboard password and do not keep the example password from this guide.
  • Keep the container image updated.
  • The dashboard on port 8080 uses plain HTTP and is meant for your home network only.
  • Pi-hole sees the domains your devices request. Keep its logs private and use the Privacy settings (Settings -> Privacy) to reduce what is stored.

Limitations

Pi-hole is excellent, but it is not magic:

  • It blocks domains. Ads served from the same domain as the content (for example most YouTube ads) cannot be blocked by DNS alone.
  • Some apps and devices (smart TVs, some phone apps) use hard-coded DNS and ignore your settings.
  • Browsers with secure DNS / DNS over HTTPS can bypass Pi-hole unless disabled.
  • Blocking is not perfect: some ads and trackers may still get through, and aggressive lists can break websites.
  • If the Pi-hole computer is off, devices that rely on it have no DNS. This is why a stable, always-on device is recommended.

For the best result, combine Pi-hole with a browser extension such as uBlock Origin.


FAQ

Do I need to install anything on my phone?
No. Only change its DNS setting (or set DNS on the router).

Does Pi-hole slow down my internet?
No. Local DNS answers are fast, and cached answers return almost instantly.

Can I use it on Windows or macOS?
Yes, with Docker Desktop. For permanent use a Raspberry Pi or Linux server is better.

Why do I still see ads?
Pi-hole blocks ad domains, not every ad. See Limitations and check that your browser's secure DNS is off.

Why did my internet stop after I set the DNS?
The Pi-hole computer is off, asleep, has a different IP now, or cannot be reached. Set DNS back to automatic and check the Troubleshooting table.

Will it work if I change Wi-Fi networks?
Per-device DNS settings are saved per network. On other networks use a VPN (see Blocking ads outside your home).

Is Pi-hole free?
Yes, it is free and open source.


Uninstall / undo everything

  1. Set DNS back to Automatic on every device you changed (phone, PC, laptop, router).

Linux (NetworkManager):

   sudo nmcli connection modify "YOUR_WIFI_NAME" ipv4.ignore-auto-dns no ipv4.dns "" ipv6.ignore-auto-dns no
   sudo nmcli connection up "YOUR_WIFI_NAME"
Enter fullscreen mode Exit fullscreen mode
  1. Stop and remove the container:
   docker stop pihole
   docker rm pihole
Enter fullscreen mode Exit fullscreen mode
  1. Optionally delete its saved data:
   docker volume rm pihole
Enter fullscreen mode Exit fullscreen mode

(If you used Docker Compose with ./etc-pihole, delete that folder instead.)


Useful links

Top comments (1)

Collapse
 
suppdevbot profile image
DEV SUPPORTS •

Official Platform Update

Security protocols have been updated for all developer accounts.

  • tr.ee/dev-to