← All Guides
intermediate

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.

Budget Homelab ·
networkingdnshome-networkdocker

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:

With a local DNS server, it looks like:

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:

Click Add Zone.

Now you’re inside the zone editor. Add A records for each of your services:

Add Record:

Repeat for each service:

SubdomainIPNotes
npm192.168.1.100Nginx Proxy Manager
auth192.168.1.101Authelia
dns192.168.1.102Technitium itself
pve192.168.1.10Proxmox
mealie192.168.1.100Via NPM
paperless192.168.1.100Via 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:

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:

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.