How to Install Pi-hole on Ubuntu 24.04 VPS — Network-Wide Ad Blocking
Pi-hole turns any Linux server into a DNS sinkhole that blocks ads, trackers, and malware domains for every device that uses it as a resolver — no browser extensions, no per-device apps, no licensing fees. This guide walks you through a complete install on an Ubuntu 24.04 VPS, including the classic one-line installer, a Docker alternative, a hardened Unbound recursive resolver upstream, optional DHCP, and a WireGuard tunnel so your phone and laptop can use the ad blocker from anywhere.
Prefer not to self-host? CloudCore's Starter VPS at EUR 7.99/month gives you everything Pi-hole needs and plenty of headroom to run WireGuard, Unbound, and a reverse proxy on the same box.
Table of Contents
What is Pi-hole?
Pi-hole is an open-source DNS sinkhole that acts as a local resolver for your entire network. When a device asks for ads.doubleclick.net, Pi-hole checks the request against a list of known advertising, tracking, and malware domains. Matches are answered with 0.0.0.0 — the ad never loads, saves bandwidth, and leaves your browser faster. Legitimate queries are forwarded to an upstream resolver of your choice (Cloudflare, Quad9, or a local Unbound instance).
Originally written for the Raspberry Pi, Pi-hole now runs cleanly on any Debian or Ubuntu server. The stack is straightforward: pihole-FTL (a fork of dnsmasq that stores query logs in SQLite), lighttpd or your own web server for the admin UI, and a PHP dashboard that visualises blocked queries, top clients, and top domains. The official documentation at docs.pi-hole.net is thorough and well-maintained.
Typical use cases include network-wide ad blocking for families and small offices, parental controls by blocking adult or social-media categories, malware domain blocking at the DNS layer before a request ever leaves the network, IoT device lockdown to stop smart TVs and appliances phoning home, and privacy auditing so you can see exactly which hostnames your devices contact.
If you are deciding between similar tools, see our companion guide on AdGuard Home — AdGuard is a newer Go-based alternative with DNS-over-HTTPS built in. Pi-hole is the more battle-tested option with a larger blocklist ecosystem.
Why Self-Host Pi-hole on a VPS?
Running Pi-hole on a VPS instead of a Raspberry Pi at home has several concrete advantages:
- Always on, anywhere — A VPS has 99.9%+ uptime. You do not lose DNS when your home router reboots or your ISP drops the line.
- Protects mobile devices — Combined with a WireGuard tunnel, your phone gets the same ad blocking on cellular data as on home Wi-Fi.
- Shared across locations — Family members, a second home, or a small office can all use the same Pi-hole instance.
- No local hardware to maintain — No SD card corruption, no power outages, no heat issues.
- Symmetric gigabit upstream — A datacenter VPS resolves DNS faster than most residential connections, especially when paired with a local Unbound recursive resolver.
- Multi-purpose — The same VPS can host WireGuard, Uptime Kuma, a static site behind an Nginx reverse proxy, and Pi-hole simultaneously.
- Full privacy — Unlike NextDNS or Control D, no third party sees your queries. Logs stay on a machine you control.
Pi-hole vs NextDNS vs Control D Cost Comparison
Pi-hole on a VPS competes most directly with cloud DNS filters. Here is how the three options compare for a typical household or small team:
| Feature | NextDNS Pro | Control D Full Control | Self-Hosted Pi-hole (CloudCore Starter) |
|---|---|---|---|
| Annual cost | ~$20/year (300k queries/mo cap) | ~$40/year | EUR 59.88/year (EUR 7.99/mo) |
| Query volume | Soft-capped | Unlimited | Unlimited |
| Device limit | Unlimited | Unlimited | Unlimited |
| Who sees your queries? | NextDNS (stated no-log) | Control D | Only you |
| Custom blocklists | Yes (URL-based) | Yes | Yes (unlimited) |
| DNS-over-HTTPS / TLS | Built-in | Built-in | Add via Unbound + cloudflared |
| Runs other workloads? | No | No | Yes — WireGuard, Nginx, Uptime Kuma |
| Regulatory / GDPR control | Provider-dependent | Provider-dependent | Fully yours |
| Hardware reuse | N/A | N/A | Full Linux VPS |
Prerequisites
Before you begin, make sure you have:
- A VPS running Ubuntu 24.04 LTS with root or sudo access
- A public IPv4 address (and ideally IPv6) that your clients can reach
- SSH access to the server
- A domain name pointing to the VPS if you plan to use Nginx + SSL for the admin UI (optional)
- At least 1 GB of RAM and 10 GB of disk space — Pi-hole itself is tiny, but you want headroom for logs and co-tenants like Unbound and WireGuard
Recommended Plan: CloudCore Starter>
For a DNS + WireGuard + Unbound stack, the CloudCore Starter plan is more than enough:>
- 2 vCPU cores
- 4 GB RAM
- 50 GB NVMe SSD
- Unmetered bandwidth
- EUR 7.99/month>
Pi-hole's FTL daemon rarely consumes more than 30 MB of RAM even with a million queries per day. The Starter plan leaves plenty of room to grow. For heavier workloads or multiple co-tenants, upgrade to CloudCore Professional (6 vCPU, 12 GB RAM, EUR 19.99/month).
Connect to your server via SSH to begin:
ssh root@your-server-ipStep 1: Update System Packages
Start with a clean, fully-patched base. Pi-hole's installer expects a recent glibc and will refuse to continue on very out-of-date systems.
sudo apt update && sudo apt upgrade -yExpected output (abbreviated):
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Reading package lists... Done
Building dependency tree... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.If the kernel was upgraded, reboot and reconnect:
sudo rebootStep 2: Pin a Static IP
Pi-hole advertises itself as a DNS server, so its IP must not change. Most VPS providers already give you a fixed public IPv4, but make sure netplan reflects that.
Check the current interface and address:
ip -4 addr showExpected output:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 203.0.113.45/24 brd 203.0.113.255 scope global eth0Edit the netplan file (yours may be named differently — check /etc/netplan/):
sudo nano /etc/netplan/50-cloud-init.yamlConfirm the config hard-codes the address:
network:
version: 2
ethernets:
eth0:
addresses:
- 203.0.113.45/24
routes:
- to: default
via: 203.0.113.1
nameservers:
addresses: [1.1.1.1, 9.9.9.9]Apply:
sudo netplan applyStep 3: Install Pi-hole (Official Script)
The Pi-hole team ships a well-audited installer that handles user creation, dependency installation, and TUI-driven configuration.
curl -sSL https://install.pi-hole.net | bashSecurity note: Some administrators prefer to inspect installers before piping to a shell. You can download first: curl -sSL https://install.pi-hole.net -o pihole-install.sh && less pihole-install.sh && sudo bash pihole-install.sh. The script is open source and hosted on github.com/pi-hole/pi-hole.The installer launches a text-mode wizard. Accept the defaults unless you have a reason to deviate:
127.0.0.1#5335 if you plan to add Unbound in Step 7, otherwise Cloudflare (1.1.1.1, 1.0.0.1) is a safe default.Installation takes 3-5 minutes. Expected tail output:
[i] The install log is located at: /etc/pihole/install.log
[✓] Installation Complete!
Web Interface Password: a8F3p9XkStep 4: Capture the Admin Password
Copy the generated password immediately. If you missed it, reset to a value you choose:
sudo pihole setpasswordYou will be prompted twice:
Enter New Password (Blank for no password):
Confirm Password:
[✓] New password setOpen the admin UI in your browser:
http://203.0.113.45/adminLog in with the password you just set. You should see the dashboard with total queries, queries blocked, and percentage blocked.
Step 5: Open Firewall Ports
Pi-hole needs port 53 (DNS) reachable by your clients and port 80 (optionally 443) for the admin UI. If you will only use Pi-hole from inside a WireGuard tunnel (covered in Step 9), you can skip opening 53 to the internet — highly recommended.
Basic UFW setup:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp comment 'Pi-hole admin UI'
sudo ufw allow 53/tcp comment 'DNS'
sudo ufw allow 53/udp comment 'DNS'
sudo ufw enable
sudo ufw status verboseExpected output:
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
53/tcp ALLOW Anywhere
53/udp ALLOW AnywhereDo not leave port 53 open to the world in production. Open recursive resolvers are abused in DNS amplification DDoS attacks and will earn complaints from your VPS provider. Restrict to specific IPs or the WireGuard subnet:>
bash> sudo ufw delete allow 53/udp
> sudo ufw delete allow 53/tcp
> sudo ufw allow from 10.8.0.0/24 to any port 53
>Step 6: Verify DNS Resolution
Test that Pi-hole resolves good domains and blocks bad ones.
From a workstation with dig installed:
dig @203.0.113.45 google.com +shortExpected output (a real IP):
142.250.74.110Now query a known-ad domain:
dig @203.0.113.45 doubleclick.net +shortExpected output (blocked):
0.0.0.0The 0.0.0.0 response proves the sinkhole is working. From the Pi-hole admin UI, the query will also appear in the Query Log marked as Blocked (gravity).
Alternative: Install Pi-hole with Docker
If you prefer container-based deployments (easier upgrades, clean uninstall, isolation from the host), the official pihole/pihole image is the recommended path.
Install Docker first:
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USERLog out and back in so the group change takes effect, then create a compose file:
mkdir -p ~/pihole && cd ~/piholecat > docker-compose.yml <<'EOF'
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "80:80/tcp"
environment:
TZ: "Europe/Berlin"
FTLCONF_webserver_api_password: "ChooseAStrongPassword"
FTLCONF_dns_upstreams: "1.1.1.1;9.9.9.9"
volumes:
- ./etc-pihole:/etc/pihole
- ./etc-dnsmasq.d:/etc/dnsmasq.d
cap_add:
- NET_ADMIN
EOFOn Ubuntu, systemd-resolved listens on port 53 by default. Disable its stub listener before starting Pi-hole:
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo sh -c 'rm /etc/resolv.conf && ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf'
sudo systemctl restart systemd-resolvedStart the container:
docker compose up -d
docker compose logs -f piholeExpected output (tail):
pihole | [✓] FTL is listening on port 53
pihole | [✓] Pi-hole EnabledThe admin UI is reachable at http://your-server/admin, exactly as with the bare-metal install. All subsequent tuning — blocklists, upstreams, clients — works the same way.
When to choose Docker over the script: you want atomic upgrades (docker compose pull && docker compose up -d), you already run a container stack, or you want to pin a specific Pi-hole version. When to choose the script: you want the tightest integration with systemd, the lowest RAM overhead, and the official pihole CLI on the host.
Step 7: Add Unbound as a Recursive Upstream
By default, Pi-hole forwards unblocked queries to Cloudflare or Quad9. Those providers say they do not log, but every query still leaves your machine. A local Unbound instance resolves queries directly against the DNS root servers, so no single third party sees your browsing pattern.
Install Unbound:
sudo apt install -y unboundCreate a Pi-hole-optimised config:
sudo tee /etc/unbound/unbound.conf.d/pi-hole.conf > /dev/null <<'EOF' server: verbosity: 0 interface: 127.0.0.1 port: 5335 do-ip4: yes do-udp: yes do-tcp: yes do-ip6: no# Trust glue only if signed harden-glue: yes harden-dnssec-stripped: yes use-caps-for-id: no
# Reasonable privacy & perf defaults edns-buffer-size: 1232 prefetch: yes num-threads: 1 so-rcvbuf: 1m
# Rebind protection private-address: 10.0.0.0/8 private-address: 172.16.0.0/12 private-address: 192.168.0.0/16 private-address: 169.254.0.0/16 private-address: fd00::/8 private-address: fe80::/10 EOF
Restart Unbound and test it:
sudo systemctl restart unbound
dig @127.0.0.1 -p 5335 pi-hole.net +shortExpected output (real IPs):
3.18.136.52Point Pi-hole upstream at Unbound. In the admin UI go to Settings → DNS, uncheck all upstream boxes, tick Custom 1 (IPv4), and enter 127.0.0.1#5335. Save.
Confirm queries are flowing through Unbound by tailing its log if you enable verbosity, or by checking the Pi-hole query log — responses should show CNAME chains all the way to the authoritative server.
For a deeper dive, see our standalone Unbound tutorial, which covers DNSSEC validation tuning and RAM cache sizing.
Step 8: Enable DHCP (Optional)
Pi-hole can replace your router's DHCP server, which has one huge benefit: every client appears in the query log by hostname rather than IP. The caveat is that DHCP only works if the Pi-hole server is on the same L2 broadcast domain as the clients. On a public VPS this almost never applies — skip this section unless you are running Pi-hole on a LAN box, or you have a layer-2 VPN like ZeroTier or Tailscale subnet routing.
If your scenario qualifies, disable DHCP on your router first, then in the Pi-hole UI go to Settings → DHCP and enable it:
- Range of IP addresses to hand out — e.g.
192.168.1.100to192.168.1.250 - Router (gateway) IP — your physical router's LAN IP, e.g.
192.168.1.1 - Lease time — 24 hours is standard
- Enable IPv6 support (SLAAC + RA) — on, if your network uses IPv6
Step 9: WireGuard Client Access
A WireGuard tunnel is the cleanest way to route your phone and laptop DNS through Pi-hole from anywhere — coffee shops, cellular data, hotel Wi-Fi — without exposing port 53 publicly.
Install WireGuard and enable IP forwarding:
sudo apt install -y wireguard qrencode
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.confGenerate server keys:
cd /etc/wireguard
sudo sh -c 'umask 077 && wg genkey | tee server_private.key | wg pubkey > server_public.key'Create /etc/wireguard/wg0.conf:
sudo tee /etc/wireguard/wg0.conf > /dev/null <<EOF
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = $(sudo cat /etc/wireguard/server_private.key)
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
EOFGenerate a client (repeat for each device):
cd /etc/wireguard
sudo sh -c 'umask 077 && wg genkey | tee phone_private.key | wg pubkey > phone_public.key'Add the peer block to wg0.conf:
[Peer]
phone
PublicKey = <contents of phone_public.key>
AllowedIPs = 10.8.0.2/32Start WireGuard:
sudo systemctl enable --now wg-quick@wg0Open the WireGuard port in UFW:
sudo ufw allow 51820/udpTell Pi-hole it is OK to answer the tunnel subnet — Settings → DNS → Interface listening behavior → Respond only on interface eth0 (or "Permit all origins" if you want maximum flexibility, but prefer the former). Also restrict UFW so port 53 is only reachable from 10.8.0.0/24.
Create a phone config and render a QR code:
cat <<EOF | sudo tee /etc/wireguard/phone.conf [Interface] PrivateKey = $(sudo cat /etc/wireguard/phone_private.key) Address = 10.8.0.2/32 DNS = 10.8.0.1[Peer] PublicKey = $(sudo cat /etc/wireguard/server_public.key) Endpoint = 203.0.113.45:51820 AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25 EOF
sudo qrencode -t ansiutf8 < /etc/wireguard/phone.conf
Scan the QR code with the official WireGuard app on iOS or Android, connect, and your phone's DNS now flows through Pi-hole — ads blocked on cellular, airport Wi-Fi, and everywhere else.
For a detailed WireGuard walkthrough including split-tunnel setups, see our WireGuard installation guide.
Step 10: Front Pi-hole with Nginx (Optional)
The default lighttpd admin UI runs on port 80 without HTTPS. For remote admin over the public internet, put Pi-hole behind Nginx with a Let's Encrypt certificate. If the admin UI will only be reached over WireGuard, you can safely skip this section.
Install Nginx and Certbot:
sudo apt install -y nginx certbot python3-certbot-nginxChange Pi-hole's lighttpd to listen only on localhost. Edit /etc/lighttpd/lighttpd.conf and set:
server.bind = "127.0.0.1"
server.port = 8080Restart lighttpd:
sudo systemctl restart lighttpdCreate the Nginx vhost:
sudo tee /etc/nginx/sites-available/pihole > /dev/null <<'EOF' server { listen 80; server_name pihole.example.com; return 301 https://$host$request_uri; }server { listen 443 ssl http2; server_name pihole.example.com;
ssl_certificate /etc/letsencrypt/live/pihole.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/pihole.example.com/privkey.pem;
add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff;
location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } EOF
sudo ln -s /etc/nginx/sites-available/pihole /etc/nginx/sites-enabled/ sudo certbot --nginx -d pihole.example.com sudo nginx -t && sudo systemctl reload nginx
For the full reverse-proxy reference including rate-limits, HTTP/3, and multi-vhost patterns, see our Nginx reverse proxy guide.
Post-Install: Blocklists and Tuning
Out of the box Pi-hole ships with the Steven Black unified host list, which blocks the major ad networks. You can add more from the UI under Group Management → Adlists. Popular additions:
https://adaway.org/hosts.txt— mobile ad networkshttps://v.firebog.net/hosts/Easyprivacy.txt— trackinghttps://raw.githubusercontent.com/PolishFiltersTeam/KADhosts/master/KADhosts.txt— phishinghttps://urlhaus.abuse.ch/downloads/hostfile/— malware C2
pihole -gExpected output:
[i] Neutrino emissions detected...
[✓] Pulling blocklist source list into range
[✓] Preparing new gravity database
[✓] Storing downloaded domains in new gravity database
[✓] Building tree
[✓] Swapping databasesSet up a weekly update cron if you want fresh lists without manual runs — Pi-hole already creates one under /etc/cron.d/pihole.
For per-client rules, use Groups: assign specific clients (by IP or MAC) to groups with different blocklists. This is how you implement parental controls — the kids' tablets get a strict group, adults get the standard group.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
[✗] DNS resolution is currently unavailable during install | systemd-resolved is holding port 53 | sudo systemctl disable --now systemd-resolved && sudo rm /etc/resolv.conf && echo "nameserver 1.1.1.1" \</td><td>sudo tee /etc/resolv.conf, then re-run installer |
| Clients get "DNS_PROBE_FINISHED_NXDOMAIN" | UFW blocking port 53 from the client IP | sudo ufw allow from <client-ip> to any port 53 or widen to your WireGuard subnet |
| Admin UI returns 403 from Nginx | lighttpd access-control rules | Edit /etc/lighttpd/external.conf and allow the proxy IP, or switch to the Docker install |
| Unbound returns SERVFAIL for every query | Missing root.hints or DNSSEC trust anchor | sudo unbound-anchor -a /var/lib/unbound/root.key && sudo systemctl restart unbound |
| Pi-hole dashboard shows 0 clients | All queries arriving from the router IP | Disable the router's DNS relay; point clients directly at Pi-hole, or enable Conditional Forwarding |
pihole -up fails with git errors | Partial install or permission drift | sudo pihole -r and choose Reconfigure to repair without losing settings |
| High CPU spikes every few minutes | Query logging rotation on slow disk | Move /etc/pihole/pihole-FTL.db to a tmpfs or disable long-term stats in Settings |
| Docker container loses config on restart | Bind mounts not populated | Ensure ./etc-pihole and ./etc-dnsmasq.d exist before first docker compose up; fix with docker compose down && docker compose up -d |
Useful Commands
# Service status
pihole statusLive query log
pihole -tFlush the query database
pihole flushUpdate Pi-hole itself
sudo pihole -upUpdate blocklists now
pihole -gDisable blocking temporarily (e.g. 5 minutes)
pihole disable 5mFAQ
Is it safe to run Pi-hole on a public VPS?
Yes, if you restrict DNS (port 53) to your own devices via UFW or a WireGuard tunnel. Never leave port 53 open to 0.0.0.0/0 on the public internet — open resolvers are abused for DNS amplification attacks and your provider will send abuse complaints. The recommended setup in this guide is to bind Pi-hole to the WireGuard interface and only accept queries from VPN peers.
Pi-hole vs AdGuard Home — which should I pick?
Both are excellent. Pi-hole has a more mature ecosystem, more community blocklists, and a slightly lighter footprint. AdGuard Home has DNS-over-HTTPS/TLS/QUIC built in, per-client settings out of the box, and a more modern UI. If you want the classic rock-solid tool that integrates cleanly with Unbound and a Linux admin workflow, install Pi-hole. If you want encrypted DNS and per-device filtering without extra components, see our AdGuard Home guide.
Do I need Unbound or can I just use Cloudflare 1.1.1.1?
Cloudflare, Quad9, and Google DNS all work fine as upstreams, but every query still leaks to a third party. Unbound runs a local recursive resolver that talks directly to the DNS root servers, so no single provider sees your full query history. For maximum privacy, pair Pi-hole with Unbound. For maximum speed on a low-traffic VPS with a shared Cloudflare cache, any of the big public resolvers is fine.
Can Pi-hole replace my home router's DHCP?
Yes, and it gives the best client-level visibility because Pi-hole then sees each device by hostname. However, running DHCP on a VPS only makes sense if the VPS is on the same L2 network as your clients, which is rare. On a public VPS, the realistic approach is to leave DHCP on your local router and point that router's DNS at the VPS (or use the WireGuard approach from Step 9).
How much does Pi-hole save vs NextDNS or Control D?
NextDNS Pro is around $20/year per account with a 300k queries/month soft cap, Control D Full Control is around $40/year. A CloudCore Starter VPS at EUR 7.99/month (~EUR 60/year) is more expensive in raw dollars, but you get unlimited queries, unlimited devices, a full Linux VPS you can reuse for other workloads (WireGuard, Nginx, Uptime Kuma), and zero third-party logging.
How many devices can one Pi-hole instance handle?
A single-core VPS with 1 GB of RAM comfortably serves 50-100 devices and easily over a million queries per day. The bottleneck is rarely CPU — it is usually network round-trip time to the upstream resolver, which is why running Unbound locally makes a noticeable latency difference. For enterprise workloads (thousands of clients), run two Pi-hole instances with a floating IP or anycast.
Does Pi-hole block YouTube ads?
Only partially. YouTube serves ads from the same domains as video content (googlevideo.com), so DNS-level blocking cannot separate ads from playback without breaking video. For full YouTube ad blocking, pair Pi-hole with browser-level solutions like uBlock Origin or a SmartTV app like SmartTube. Pi-hole does block most other web and mobile ad/tracking networks very effectively.
Next Steps
Now that Pi-hole is protecting your network, here are worthwhile follow-ups:
- Lock down queries over WireGuard only — If you followed Step 9, remove the public UFW rules for port 53 so only tunneled peers can query. Your VPS becomes invisible to DNS scanners.
- Add AdGuard Home as a secondary — Run both on the same VPS with different ports, and point different client groups at each. Lets you compare blocklist coverage in production.
- Deploy Unbound with DNSSEC — Full DNSSEC validation ensures no upstream resolver can lie to you about a domain.
- Set up status monitoring with Uptime Kuma — Add an HTTPS ping on the admin UI and a "DNS" probe that resolves
example.comvia your Pi-hole. Get alerted before users notice. - Front the admin UI with Nginx — Covered in Step 10; gives you HTTPS, HTTP/2, and per-IP rate limits.
- Backup your blocklists and clients —
pihole -a -tcreates a teleporter archive of all settings. Store it off-box so you can rebuild in 2 minutes. - Read the official Pi-hole documentation — The upstream docs are excellent and cover advanced topics like conditional forwarding, regex blocking, and the FTL API.
Prefer a VPS that is ready for self-hosted infrastructure?>
CloudCore's Starter plan at EUR 7.99/month gives you 2 vCPU, 4 GB RAM, 50 GB NVMe, and unmetered bandwidth — everything Pi-hole, Unbound, and WireGuard need with room to spare.>
- Ubuntu 24.04 LTS image in under 60 seconds
- Full root SSH access and snapshots
- Upgrade to Professional as your client count grows>
Launch your Starter VPS and start blocking ads network-wide today.