If you've ever counted the ads on a single news article page, you already know why people bother with Pi-hole. It's a small piece of software that blocks ads and trackers for every device on your network at once — no browser extensions, no per-device setup, no fighting with your smart TV's built-in ad blocker (because it doesn't have one). Run it once on your network, and your phone, laptop, streaming box, and that one smart speaker you don't fully trust all get the same protection automatically.
The catch is that Pi-hole needs somewhere to live 24/7, and dedicating a physical Raspberry Pi to it — while it works, and gave the project its name — is overkill if you're already running Proxmox VE. An LXC container gives you the same always-on DNS server with a fraction of the hardware, none of the SD card wear, and the ability to snapshot and restore it in seconds if you break something. This guide walks through the whole setup, from a bare Proxmox host to ads disappearing on your phone.
What You Will Learn
- What Pi-hole actually does and how it blocks ads at the DNS level
- Why an LXC container is a better home for it than a dedicated Raspberry Pi
- How to deploy Pi-hole using the community-scripts LXC installer
- How to give the container a static IP so your network can rely on it
- How to point your router or individual devices at Pi-hole for DNS
- The errors people run into most often, and what actually causes them
What Is This Feature?
Pi-hole is an open-source DNS server that filters out ad and tracker domains before your devices can even connect to them. Every time an app or website tries to load an ad, it first has to look up the ad server's address through DNS — the system that translates domain names like doubleclick.net into IP addresses. Pi-hole sits between your devices and the internet's DNS, and when it sees a request for a domain on one of its blocklists, it simply refuses to answer. No IP address comes back, so the ad never loads.
This is different from a browser ad blocker like uBlock Origin, which only works inside that one browser and has to hide ads after they've already loaded. Pi-hole blocks the request before it leaves your network, which means it also works on devices that can't run extensions at all — your Roku, your smart fridge, your kid's tablet.
LXC, short for Linux Containers, is the lightweight virtualization technology built into Proxmox VE. Unlike a full virtual machine, an LXC container shares the host's Linux kernel instead of booting its own, so it starts almost instantly and uses a lot less RAM and disk. For something like Pi-hole, which just needs to run a small DNS service around the clock, that's a much better fit than a full VM.
Why Would You Use It?
Once Pi-hole is running and your network is pointed at it, ads and trackers just stop showing up — on every device, all the time, with zero per-device configuration. A lot of people notice their phone feels faster on Wi-Fi at home simply because pages aren't loading a dozen tracking scripts anymore.
Running it as a Proxmox LXC container specifically buys you a few things a standalone Raspberry Pi can't easily give you. You get snapshots, so you can roll back a broken update in seconds instead of re-flashing an SD card. You get real backups through Proxmox's built-in vzdump or Proxmox Backup Server. And you get to run it on hardware you're probably already leaving on 24/7 anyway, instead of adding another device to your network closet.
One honest caveat: Pi-hole becomes a single point of failure for DNS on your network. If the container is down and nothing else is configured to answer DNS queries, devices can lose internet access even though the internet connection itself is fine. It's a rare problem in practice, but it's worth knowing before you make it the only DNS server your router points to.
Prerequisites
- A working Proxmox VE 8.x or 9.x host with internet access (this guide was tested on 9.2)
- Root access to the Proxmox shell, through the web console or SSH
- At least 4 GB of free storage and 512 MB of free RAM — Pi-hole is genuinely light
- Access to your router's admin page, if you want to set Pi-hole as the network-wide DNS server
- A rough idea of your local subnet, for example
192.168.1.0/24
Step-by-Step Tutorial
1. Open the Proxmox VE shell
Log into the Proxmox web interface, click your node's name in the left-hand tree, and select Shell from the top toolbar. SSH works just as well if that's what you're used to.
2. Run the community-scripts installer
The community-scripts project maintains a well-tested library of LXC installers for Proxmox, including one for Pi-hole. Paste this into the shell:
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/pihole.sh)"
You'll get a text-based menu. The default settings are fine for almost everyone — they create an unprivileged container on Debian 12, with 1 CPU core, 512 MB of RAM, and a 4 GB disk. Pi-hole barely touches those resources under normal home use, so there's rarely a reason to bump them up.
The script downloads the Debian template, creates the container, installs Pi-hole's dependencies, and runs the Pi-hole installer inside it automatically. On a typical connection this takes three to five minutes. When it's done, it prints the container's IP address and the auto-generated admin password — copy both somewhere safe before you close the terminal, because the password won't be shown again.
3. Give the container a static IP
DNS servers need a fixed address — if Pi-hole's IP changes after a DHCP lease renewal, every device pointed at it loses DNS resolution until you update the setting everywhere. In the Proxmox web UI, click on the new container, go to Network, and edit net0. Switch from DHCP to a static IP, for example 192.168.1.53/24, and set the gateway to your router's address.
If you'd rather do it from the shell, edit the container's config directly on the host:
nano /etc/pve/lxc/<CTID>.conf
and change the net0 line to include ip=192.168.1.53/24,gw=192.168.1.1 instead of ip=dhcp. Restart the container afterward with pct reboot <CTID> for the change to take effect.
4. Log in to the Pi-hole dashboard
From any device on the same network, open a browser and go to http://<container-ip>/admin. Log in with the password the installer gave you. The dashboard shows queries in real time once devices start using it, along with how many were blocked and which domains were the worst offenders.
Change the password to something you'll actually remember by running pihole -a -p inside the container if you'd rather not keep the auto-generated one.
5. Point your network at Pi-hole
This is the step that actually turns Pi-hole on for your whole network. Log into your router's admin page, find the DNS settings — usually under WAN or LAN/DHCP settings depending on the brand — and set the primary DNS server to your container's static IP. Leave the secondary DNS blank, or point it at the same address again; if you set a secondary to your ISP's DNS, some devices will fall back to it and skip Pi-hole entirely when the primary is briefly slow to respond.
If you'd rather test things first without touching the whole network, set the DNS manually on just one device — your laptop's Wi-Fi settings, for example — and confirm ads disappear before you commit the whole household to it.
Commands Explained
| Command | What it does |
|---|---|
bash -c "$(curl -fsSL <script-url>)" | Downloads the community-scripts installer and runs it immediately — this is what creates the container and installs Pi-hole |
pct list | Run on the Proxmox host, lists every LXC container along with its ID and current status |
pct enter <CTID> | Opens a root shell directly inside the container without needing SSH |
pihole -up | Run inside the container, updates Pi-hole's core, web interface, and blocklists to the latest version |
pihole -a -p | Sets or changes the admin dashboard password from the command line |
pihole status | Shows whether the DNS resolver (FTL) is currently active and listening |
Common Errors
Devices lose internet access after switching DNS. Almost always means Pi-hole's container isn't reachable — check that it's running with pct list, and that you set the static IP correctly. If the container itself is fine, double-check the router's DNS field for a typo.
The dashboard shows 0 queries even though devices are using it. Some devices, especially phones running iOS 14 or newer and some Android versions, use "Private DNS" or DNS-over-HTTPS settings that bypass your router entirely. Check the device's network settings and make sure Private DNS is set to automatic or off, not pointed at a third-party provider.
"Unable to complete update, please contact support" during pihole -up. This usually means the container ran out of disk space, since Pi-hole downloads fresh blocklists during updates. Check free space with df -h inside the container — 4 GB is normally plenty, but it's worth checking if you customized the disk size down.
Some sites break entirely, not just their ads. A handful of blocklists are aggressive enough to catch domains that a site actually needs to function, not just ads. Check the Query Log in the dashboard, find the blocked domain the broken site needed, and whitelist it manually from there.
Troubleshooting
If Pi-hole seems to be blocking everything or nothing at all, start by checking whether it's actually receiving queries. The dashboard's live query log updates in real time — browse to any website on a device you've pointed at Pi-hole, and you should see requests appear immediately. If nothing shows up, the device isn't actually using Pi-hole for DNS yet, and the fix is almost always on the device or router side, not Pi-hole's.
For anything deeper, pct enter <CTID> from the Proxmox shell and check the FTL service directly with systemctl status pihole-FTL. If it's not running, journalctl -u pihole-FTL -n 50 will usually show you exactly why it crashed.
If DNS resolution is slow rather than broken, it's often the upstream DNS provider Pi-hole is forwarding to, not Pi-hole itself. Try switching the upstream server under Settings → DNS in the dashboard — Cloudflare's 1.1.1.1 and Quad9's 9.9.9.9 are both solid, fast defaults.
Best Practices
Set Start at boot for the container under Options in the Proxmox UI. If your Proxmox host reboots — after a power blip, say — you want DNS for the whole network to come back automatically, not sit down until you notice.
Back up the container regularly with vzdump. Pi-hole's configuration, custom blocklists, and whitelist entries live entirely inside the container, and rebuilding all of that by hand after a lost container is a genuinely annoying afternoon.
Don't rely on a single Pi-hole instance as your only DNS server if you can help it. Running a second Pi-hole container (Pi-hole supports this natively through Gravity Sync, or you can simply set your router's secondary DNS to a public resolver as a fallback) means a container crash doesn't take your whole network offline.
Update regularly, but don't automate it blindly. Run pihole -up yourself every few weeks rather than cron-ing it — blocklist updates are safe to automate, but a core version bump occasionally needs a quick look afterward to confirm nothing broke.
Frequently Asked Questions
Will Pi-hole block ads inside YouTube or Twitch?
Mostly no. In-stream video ads are usually served from the same domains as the video content itself, so DNS-level blocking can't separate the ad from the video without also breaking playback. Pi-hole is very effective against banner ads, tracking scripts, and most in-app ads, just not that specific category.
Does Pi-hole slow down my internet?
No — if anything, it tends to feel faster, since blocked requests never happen and legitimate DNS answers get cached locally after the first lookup. The container itself adds a few milliseconds of DNS lookup time at most, which isn't noticeable in normal use.
Can I run Pi-hole in a VM instead of an LXC container?
Yes, and it works fine either way. LXC just starts faster, uses less RAM, and is easier to back up for a lightweight always-on service like this. There's no functional difference in what Pi-hole itself does.
What happens if the Pi-hole container goes down?
Devices configured to use it as their only DNS server will be unable to resolve domain names until it's back up, even though the actual internet connection is unaffected. Setting a fallback DNS server, or running a second Pi-hole instance, avoids this.
Do I need to keep updating the blocklists manually?
No. Pi-hole automatically refreshes its blocklists on a schedule you can set under Settings → DNS, once a week by default. You only need to run pihole -up yourself for actual software updates.
Conclusion
Ten minutes with the community-scripts installer, one static IP, and a single DNS setting on your router is genuinely all it takes to strip ads and trackers off every device in your house at once. It's one of the more satisfying homelab projects precisely because the result is so visible — half the internet just looks cleaner the moment you switch your DNS over.
Give it a day running on one test device before you commit your whole network to it, keep an eye on the query log for anything getting blocked that shouldn't be, and set up a backup once you're happy with it. After that, it's the kind of service that just quietly does its job in the background for years.