How to Set Up a Local DNS Server With Technitium (Ditch the Router DNS)
Run Technitium DNS in Docker to get internal hostnames, ad blocking, and split DNS for your homelab — no more IP addresses in your browser.
Most home networks resolve DNS through the router, which forwards to whatever your ISP or Google or Cloudflare provides. This works fine for reaching the public internet. It does nothing for your internal services.
Without a local DNS server, reaching your homelab services looks like:
http://192.168.1.10:8096(Jellyfin)http://192.168.1.10:81(Nginx Proxy Manager)http://192.168.1.101:9091(Authelia)
With a local DNS server, it looks like:
https://jellyfin.homelab.lanhttps://npm.homelab.lanhttps://auth.homelab.lan
Technitium DNS is what I run. It’s a full recursive DNS server with a clean web UI, DHCP capability, ad blocking via DNS blocklists, and good support for the split DNS configuration that makes accessing homelab services cleanly from outside your network possible.
Before you start: You need Docker running. If not, see the Docker guide. You should also have a domain configured in Cloudflare, and Nginx Proxy Manager running for HTTPS.
Install Technitium
Create the directory and compose file:
mkdir -p ~/docker/technitium
cd ~/docker/technitium
docker-compose.yml:
services:
technitium:
image: technitium/dns-server:latest
container_name: technitium
hostname: dns-server
restart: unless-stopped
ports:
- "5380:5380/tcp" # Web UI
- "53:53/udp" # DNS
- "53:53/tcp" # DNS
volumes:
- ./config:/etc/dns
environment:
DNS_SERVER_DOMAIN: dns.home
DNS_SERVER_ADMIN_PASSWORD: changethispassword
DNS_SERVER_PREFER_IPV6: "false"
Start it:
docker compose up -d
Access the web UI at http://your-server-ip:5380. Log in with username admin and the password you set in the compose file.
Configure upstream DNS
The first thing to configure: where Technitium forwards DNS queries it can’t resolve locally.
Go to Settings → Recursion. By default it uses root hints (fully recursive). For most home setups, forwarding to Cloudflare or Google is simpler and slightly faster.
Under Settings → Forwarders, add:
1.1.1.1
1.0.0.1
Or use DNS-over-HTTPS for encrypted upstream queries:
https://cloudflare-dns.com/dns-query
https://dns.google/dns-query
Add your internal zone
This is the part that makes internal hostnames work. You’re creating a DNS zone for your internal domain that Technitium answers authoritatively.
Go to Zones → Add Zone:
- Zone:
homelab.lan(or whatever your internal domain is) - Type: Primary Zone
Click Add Zone.
Now you’re inside the zone editor. Add A records for each of your services:
Add Record:
- Name:
npm(becomesnpm.homelab.lan) - Type: A
- IPv4 Address:
192.168.1.100(your NPM server’s IP) - TTL: 60
Repeat for each service:
| Subdomain | IP | Notes |
|---|---|---|
npm | 192.168.1.100 | Nginx Proxy Manager |
auth | 192.168.1.101 | Authelia |
dns | 192.168.1.102 | Technitium itself |
pve | 192.168.1.10 | Proxmox |
mealie | 192.168.1.100 | Via NPM |
paperless | 192.168.1.100 | Via NPM |
For services that route through NPM, all the subdomains point to NPM’s IP. NPM reads the hostname from the request and routes it to the right backend container.
The wildcard record approach
If all your services run through NPM, you can add a single wildcard A record instead of individual records:
Add Record:
- Name:
*(asterisk) - Type: A
- IPv4 Address:
192.168.1.100
This makes *.homelab.lan resolve to NPM’s IP for any subdomain. Combined with NPM’s proxy hosts and wildcard SSL certificate, you can add new services without touching DNS every time.
I use this approach. The only services with dedicated DNS records are ones that don’t route through NPM (like Proxmox’s management interface at pve.homelab.lan).
Point your network to Technitium
For Technitium to resolve internal names for all your devices, they need to use it as their DNS server.
Option 1: Router DHCP (recommended)
Log into your router and change the DHCP DNS setting to your Technitium server’s IP. All devices that get their IP via DHCP will automatically start using it.
The exact location varies by router. Look for DHCP settings, then a “DNS server” field. Change it from your router’s IP (or 8.8.8.8/1.1.1.1) to your Technitium server IP.
Option 2: Static DNS per device
On each device, manually set the DNS server to your Technitium IP. More work but doesn’t require router access.
Option 3: Set it only on the Docker host
Edit /etc/resolv.conf on the server itself (or /etc/systemd/resolved.conf):
sudo systemctl edit --full systemd-resolved
Add:
[Resolve]
DNS=192.168.1.102
Domains=~homelab.lan
This sets it for the server without affecting your whole network.
Configure split DNS for Tailscale
This is what makes your internal hostnames work when you’re away from home via Tailscale.
In the Tailscale admin console: DNS → Add nameserver → Custom
Enter your Technitium server’s Tailscale IP (the 100.x.x.x address) and set the restricted domain to homelab.lan (your internal zone).
When you’re on Tailscale outside your home network, your device will ask Technitium to resolve homelab.lan names. Since Technitium knows your internal IPs and you can reach those IPs via Tailscale subnet routing, everything resolves correctly.
Full Tailscale + split DNS setup →
Add DNS blocklists (bonus)
Technitium supports blocking domains from common ad/malware lists, similar to Pi-hole.
Go to Settings → Blocking → Quick Add. There are several built-in lists to add directly. The “Steven Black” combined list is a solid starting point.
Restart the DNS server after adding blocklists to apply them.
Troubleshooting
nslookup returns wrong IP: Your device is still using the old DNS server. Flush the DNS cache:
- macOS:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder - Windows:
ipconfig /flushdns - Linux:
systemd-resolve --flush-caches
Service not resolving at all: Check that the A record is in the right zone and spelled correctly. Test directly against Technitium: nslookup npm.homelab.lan 192.168.1.102
Port 53 already in use: On Ubuntu, systemd-resolved listens on port 53 by default. Disable it:
sudo systemctl disable --now systemd-resolved
sudo unlink /etc/resolv.conf
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
Then restart Technitium.