Skip to content

Self-host Pi-hole

updated Sep 2026prices checked · Jul 2026Install verified on Ubuntu 26.04 · Sep 2026 · how we test
We earn commissions when you shop through the links below. Full disclosure →

A DNS sinkhole that blocks ads and trackers for every device on your network — no client software needed. Runs on almost nothing and gives you a tidy dashboard of what your network is really talking to.

Key facts

CategoryNetwork-wide ad blocking
LicenseEUPL-1.2
StackC (pihole-FTL)
Min RAM512 MB
Official imageyes
Measured idle RAM10 MB
Difficulty
Our recommendation

Pick Pi-hole when you want the DNS sinkhole with the largest community behind it: a decade of block lists, guides and add-ons, an optional DHCP server, and a documented floor of 512 MB of RAM and 2 GB of disk — that RAM figure is upstream's. Since v6 the `pihole-FTL` binary is the whole server (DNS, API and web UI on 80/443), the container is the officially supported Docker route, and the licence is EUPL-1.2. It blocks at the DNS layer only, so it shares AdGuard Home's ceiling on YouTube and in-app ads.

What you need

  • Any VPS with at least 512 MB of RAM
  • A domain you control — most self-hosted setups need HTTPS in front of them
  • Under an hour if you've used Docker before
Where to host itaffiliate disclosure
Hetzner Cloudrun it on
From $23.59/mo · 2 vCPU / 4 GB / 80 GB · EU + US
Get Hetzner Cloud (opens in new tab)
Kamaterafree trial
From $4/mo · 1 vCPU / 1 GB / 20 GB · US + EU + Asia
Start free on Kamatera → (opens in new tab)
DigitalOceanalso works on
From $6/mo · 1 vCPU / 1 GB / 25 GB · US + EU + Asia
Deploy on DigitalOcean → (opens in new tab)

Paid link — we earn a commission if you shop through it.

Install with Docker Compose

Save this as compose.yml and run docker compose up -d:

# Pi-hole — official compose quick start (github.com/pi-hole/docker-pi-hole)
services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"
      - "443:443/tcp"   # FTL generates a self-signed certificate
    environment:
      TZ: 'Etc/UTC'
      FTLCONF_webserver_api_password: 'changeme'
      # Required on Docker's default bridge network
      FTLCONF_dns_listeningMode: 'ALL'
    volumes:
      - './etc-pihole:/etc/pihole'
    cap_add:
      - NET_ADMIN   # only needed if Pi-hole is your DHCP server
      - SYS_TIME    # only needed if Pi-hole is your NTP client
      - SYS_NICE    # optional: more processing time
    restart: unless-stopped
# On Ubuntu/Fedora, free port 53 first (docs.pi-hole.net/docker/tips-and-tricks → "Disable systemd-resolved port 53"):
#   sudo sh -c 'mkdir -p /etc/systemd/resolved.conf.d && printf "[Resolve]\nDNSStubListener=no\n" | tee /etc/systemd/resolved.conf.d/no-stub.conf'
#   sudo sh -c 'rm -f /etc/resolv.conf && ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf'
#   sudo systemctl restart systemd-resolved
# docker compose up -d  →  http://SERVER_IP/admin

What you take on

Pi-hole v6 changed how the container is configured; the docker docs and prerequisites cover the traps:

non-negotiableOn Docker's default bridge network upstream sets FTLCONF_dns_listeningMode: 'ALL' — "If using Docker's default bridge network setting the dns listening mode should be set to 'ALL'" — and our snippet omits it. Add it if clients get no answers. If you set no FTLCONF_webserver_api_password, "a random password" is assigned; read it from the container log.
non-negotiablev6 renamed nearly every environment variable to an FTLCONF_ equivalent (WEBPASSWORD → FTLCONF_webserver_api_password, DNSMASQ_LISTENING → FTLCONF_dns_listeningMode, PIHOLE_DNS_ → FTLCONF_dns_upstreams, and so on); the last image with v5 components was 2024.07.0. Upgraders should keep ./etc-dnsmasq.d mounted with FTLCONF_misc_etc_dnsmasq_d: 'true' for the first v6 start.
non-negotiableFTL now serves the UI itself on 80 and 443 with a self-signed certificate you must trust or replace; if another web server holds 80/443 it "will attempt to bind to 8080/8443 instead". Docker tags are date-based (2026.07.2), not semver — the release notes list the Core, Web and FTL versions inside.
non-negotiableNothing is blocked until the network is pointed at it: set your router's DHCP DNS to Pi-hole, or disable the router's DHCP and use Pi-hole's (port 67 and NET_ADMIN). And the post-install page warns against making the host itself depend on Pi-hole — if Pi-hole fails, "your host loses DNS resolution", which "can prevent successful repair attempts".
non-negotiablePi-hole "needs a static IP address to properly function (a DHCP reservation is just fine)", and the prerequisites give 512 MB RAM and 2 GB free disk (4 GB recommended) as the hardware floor — our 512 MB figure is upstream's.

Head-to-head

More self-hosted tools

We use analytics cookies (Google Analytics, PostHog) to see which guides are useful. No ad networks, no cross-site tracking. See our privacy policy.