How to Install Pi-hole on Windows (WSL2 Guide)
I will be honest upfront: running Pi-hole on Windows via WSL2 is a compromise. It works, and there are legitimate reasons to do it, but it is not the ideal deployment for network-wide DNS filtering. If you have a spare Raspberry Pi, an old laptop, or a VPS, those are all better options. Pi-hole wants to be running 24/7 on something stable, and a Windows desktop that sleeps, reboots for updates, and runs Windows Update at 3am is not that.
That said, there are genuinely good reasons to run Pi-hole in WSL2:
- You want to test Pi-hole before buying hardware for a permanent deployment
- You work in an office environment where you cannot put a Raspberry Pi on the network but you can run software on your own workstation
- You want DNS filtering for just your own machine, not the entire network
- You are learning Linux administration and want to practice on the machine you already have
If any of those describe your situation, this guide will get Pi-hole running on your Windows machine. I will also cover the limitations honestly so you know what you are getting into.
This is not a set-and-forget deployment. WSL2 has networking quirks that make Pi-hole less reliable than a native Linux installation or a Docker deployment on a proper server. The IP address changes on reboot, WSL2 can shut down when idle, and Windows Update will restart your machine periodically. If you want reliable network-wide ad blocking, use a dedicated device. If you want to experiment and learn, carry on.
Prerequisites
- Windows 10 (version 2004 or later) or Windows 11
- WSL2 enabled (we will cover this below if you have not done it)
- Administrator access on your Windows machine
- A basic understanding of Linux commands — you will be working in a terminal
Step 1: Install WSL2
If you already have WSL2 with an Ubuntu distribution installed, skip to Step 2.
Open PowerShell as Administrator and run:
wsl --install
This installs WSL2 with Ubuntu as the default distribution. You will need to restart your machine after this completes.
After the restart, Ubuntu will launch automatically and ask you to create a username and password. These are your Linux credentials, separate from your Windows login.
If you already have WSL1, upgrade to WSL2:
# Check your current version
wsl --list --verbose
# Set WSL2 as default
wsl --set-default-version 2
# Convert existing distro if needed
wsl --set-version Ubuntu 2
Step 2: Update Ubuntu Inside WSL2
Open your WSL2 Ubuntu terminal (search for “Ubuntu” in the Start menu) and update everything:
sudo apt update && sudo apt upgrade -y
Verify you are running WSL2 (not WSL1) from inside the terminal:
cat /proc/version
You should see “microsoft” in the kernel version string, confirming you are in WSL.
Step 3: Fix the systemd-resolved Conflict
WSL2 Ubuntu has the same systemd-resolved port 53 conflict as a regular Ubuntu installation. The fix is identical.
First, check if systemd is running in your WSL2 instance. Recent versions of WSL2 support systemd natively:
ps -p 1 -o comm=
If this returns systemd, you have systemd running and need to disable the stub listener:
sudo nano /etc/systemd/resolved.conf
Set:
[Resolve]
DNSStubListener=no
DNS=1.1.1.1
FallbackDNS=8.8.8.8
Then:
sudo rm /etc/resolv.conf
sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
sudo systemctl restart systemd-resolved
If systemd is not running (older WSL2 versions), you may need to handle resolv.conf differently. WSL2 auto-generates /etc/resolv.conf on startup. To prevent this and set your own DNS:
# Prevent WSL from overwriting resolv.conf
sudo bash -c 'cat > /etc/wsl.conf << EOF
[network]
generateResolvConf = false
EOF'
# Set DNS manually
sudo rm /etc/resolv.conf
sudo bash -c 'echo "nameserver 1.1.1.1" > /etc/resolv.conf'
Restart WSL from PowerShell for this to take effect:
wsl --shutdown
Then reopen your Ubuntu terminal.
Step 4: Install Pi-hole
With DNS sorted, install Pi-hole using the official installer:
curl -sSL https://install.pi-hole.net | bash
The installer will walk through the same prompts as a normal Ubuntu installation. Accept the defaults for upstream DNS (Cloudflare or Google), blocklists (Steven Black), and enable the web interface.
When it asks about the network interface, select eth0. WSL2’s virtual network adapter may show a different name, but eth0 is typically correct.
Note the admin password displayed at the end, or set a new one:
pihole -a -p
Step 5: Find Your WSL2 IP Address
Here is where WSL2 gets awkward. WSL2 does not share your Windows machine’s IP address. It runs in a lightweight virtual machine with its own virtual network adapter and its own IP address. This IP address changes every time WSL2 restarts.
# Inside WSL2
ip addr show eth0 | grep 'inet '
You will see something like 172.24.176.x. This is your WSL2 IP address. It is on an internal virtual network, not directly reachable from other devices on your LAN by default.
This IP changes on every reboot. WSL2 assigns a new IP address from its virtual subnet each time it starts. Any DNS configuration pointing to this IP will break after a restart. This is WSL2’s biggest limitation for running network services. We will address this later, but be aware that it is a fundamental constraint of the platform.
Step 6: Configure Windows to Use Pi-hole
To use Pi-hole for DNS on your Windows machine, you need to point Windows at the WSL2 IP address.
The simplest method is through Windows Settings:
- Open Settings > Network & Internet > Wi-Fi (or Ethernet)
- Click your network connection, then Hardware properties
- Click Edit next to DNS server assignment
- Switch to Manual
- Enter your WSL2 IP address as the preferred DNS server
- Save
Or via PowerShell (as Administrator):
# Get your WSL2 IP
$wslIp = (wsl hostname -I).Trim()
# Get your network adapter name
Get-NetAdapter | Select-Object Name, Status
# Set DNS (replace "Wi-Fi" with your adapter name)
Set-DnsClientServerAddress -InterfaceAlias "Wi-Fi" -ServerAddresses $wslIp
Test it:
nslookup google.com $wslIp
You should get a response. If you get a timeout, Pi-hole is not listening or the WSL2 networking is not routing correctly.
Step 7: Access the Web Interface
From your Windows browser, navigate to:
http://[WSL2-IP]/admin
For example: http://172.24.176.5/admin
If the page does not load, verify Pi-hole is running inside WSL2:
pihole status
And check that the lighttpd web server is running:
sudo service lighttpd status
Making It Persistent: The Hard Part
Out of the box, this setup has two problems that make it unreliable for permanent use:
- WSL2’s IP address changes on every restart
- WSL2 can shut down automatically when idle
Fixing the IP address problem
Create a startup script that automatically updates your Windows DNS settings when WSL2 starts. Save this as a PowerShell script (e.g., C:\Scripts\update-pihole-dns.ps1):
# Get current WSL2 IP
$wslIp = (wsl hostname -I).Trim().Split(" ")[0]
# Update DNS on your network adapter
Set-DnsClientServerAddress -InterfaceAlias "Wi-Fi" -ServerAddresses $wslIp
Write-Host "Pi-hole DNS set to $wslIp"
You can run this script manually after each restart, or add it to Task Scheduler to run at login.
Preventing WSL2 from shutting down
WSL2 will terminate after a period of inactivity (8 seconds with no running processes by default in newer versions, though this has changed across Windows builds). To prevent this, you need something running inside WSL2 at all times.
The simplest approach is to configure WSL2 to start on boot and keep Pi-hole’s services alive. Add this to /etc/wsl.conf:
[boot]
systemd=true
With systemd enabled, Pi-hole’s services start automatically when WSL2 launches. But you still need WSL2 itself to start at Windows boot.
Create a scheduled task in Windows that starts WSL2 at login:
# In PowerShell as Administrator
$action = New-ScheduledTaskAction -Execute "wsl.exe" -Argument "-d Ubuntu -e /bin/bash -c 'sleep infinity'"
$trigger = New-ScheduledTaskTrigger -AtLogon
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName "Start WSL2 Pi-hole" -Action $action -Trigger $trigger -Settings $settings -Description "Keep WSL2 running for Pi-hole"
An alternative approach: You can set a static IP for WSL2 using the .wslconfig file (in your Windows user profile). Windows 11 with WSL2 version 2.0+ supports mirrored networking mode, which gives WSL2 the same IP as the host. Add to %USERPROFILE%\.wslconfig:
[wsl2]networkingMode=mirrored
This eliminates the IP address changing problem entirely, but it is only available on recent Windows 11 builds. If you are on Windows 10, you are stuck with the script approach.
Using Pi-hole for Your Machine Only vs Network-Wide
With WSL2, you have two realistic options:
Single machine (recommended for WSL2)
Configure only your Windows machine to use the WSL2 Pi-hole instance as its DNS server. This is the most reliable approach because you only need to deal with the WSL2 IP address on one machine, and if WSL2 goes down, only your machine is affected.
Network-wide (not recommended for WSL2)
You could point your router’s DNS at your WSL2 instance, but I would strongly advise against it. If your Windows machine sleeps, reboots, or WSL2 shuts down, every device on your network loses DNS. Windows Update alone will restart your machine at unpredictable times. Your family will not appreciate losing internet access at 2am because Windows decided it needed a cumulative update.
If you want network-wide filtering, deploy Pi-hole on a dedicated device. A Raspberry Pi 4 or 5 costs less than dinner out and will run Pi-hole reliably for years. See the Pi-hole on Raspberry Pi 5 guide for that approach.
The Limitations: An Honest Assessment
I want to be straight about what does not work well with this setup:
- WSL2 networking is fragile. The IP address changes, port forwarding to the LAN is not automatic, and Docker Desktop can interfere if you have it installed.
- Windows Update will restart your machine. You can delay it, but you cannot prevent it indefinitely. Your Pi-hole will go down when it does.
- Sleep and hibernate kill it. If your machine sleeps, WSL2 suspends. DNS stops. Devices that were using it lose internet access.
- Performance is fine. This is not a limitation, surprisingly. WSL2’s DNS performance is more than adequate. The bottleneck is reliability, not speed.
- No DHCP server. Pi-hole can act as a DHCP server, but in WSL2 the networking layer makes this impractical. Stick with your router for DHCP.
Troubleshooting
Pi-hole installed but DNS queries time out from Windows:
# Inside WSL2, verify Pi-hole is listening
sudo ss -lntp | grep ':53 '
# If nothing shows, restart the DNS service
pihole restartdns
Web interface not loading:
# Check lighttpd is running
sudo service lighttpd start
# Check the WSL2 IP has not changed
ip addr show eth0 | grep 'inet '
DNS works initially but stops after a while:
WSL2 has likely shut down due to inactivity. Check from PowerShell:
wsl --list --running
If nothing is listed, WSL2 has terminated. Start it again and your DNS will resume.
Docker Desktop conflicts:
If you have Docker Desktop installed, it runs its own WSL2 instance and can interfere with networking. Either use Docker Desktop’s Pi-hole deployment (see the Docker guide) or ensure Pi-hole’s WSL2 instance is the default.
Key Takeaways
- WSL2 Pi-hole is best for single-machine use. Do not rely on it for network-wide DNS filtering. Windows is not a server, and WSL2 is not designed for always-on services.
- The IP address problem is the biggest headache. WSL2 assigns a new IP on every restart. Windows 11’s mirrored networking mode fixes this, but Windows 10 users need workaround scripts.
- It is a great way to test Pi-hole. If you are evaluating whether Pi-hole is worth deploying properly, WSL2 lets you try it without buying any hardware.
- For permanent deployment, use dedicated hardware. A Raspberry Pi, an old laptop, or even a cheap VPS will give you a far more reliable Pi-hole experience than WSL2.
- The learning is still valuable. Even if the deployment is not production-grade, you are still learning DNS fundamentals, Linux administration inside WSL2, and network configuration. Those skills transfer to any platform.
Related Guides
- How to Install Pi-hole on Ubuntu 24.04 — the proper server deployment
- How to Run Pi-hole in Docker — containerised deployment with Docker Compose
- Pi-hole vs AdGuard Home — feature comparison to help you choose
- Pi-hole on Raspberry Pi 5 — dedicated hardware deployment
Related Guides
If you found this useful, these guides continue the journey:
- Pi-hole Docker Setup — Run Pi-hole in Docker for network-wide ad blocking.
- Pi-hole on Ubuntu 24.04 — Install Pi-hole directly on Ubuntu 24.04 for a dedicated DNS server.
- Pi-hole vs AdGuard Home — A hands-on comparison of the two most popular DNS ad blockers.
- Windows Fundamentals — Essential Windows knowledge for IT professionals.
- Docker Compose Beginner’s Guide — Learn how to define and manage multi-container applications.

ReadTheManual is run, written and curated by Eric Lonsdale.
Eric has over 20 years of professional experience in IT infrastructure, cloud architecture, and cybersecurity, but started with PCs long before that.
He built his first machine from parts bought off tables at the local college campus, hoping they worked. He learned on BBC Micros and Atari units in the early 90s, and has built almost every PC he’s used between 1995 and now.
From helpdesk to infrastructure architect, Eric has worked across enterprise datacentres, Azure environments, and security operations. He’s managed teams, trained engineers, and spent two decades solving the problems this site teaches you to solve.
ReadTheManual exists because Eric believes the best way to learn IT is to build things, break things, and actually read the manual. Every guide on this site runs on infrastructure he owns and maintains.
Enjoyed this guide?
New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

