Unbound is a validating, recursive, caching DNS resolver.
This repo is for a dockerised version of unbound which provides recursive DNS resolutions. This container builds unbound from source and is kept up to date with the latest security patches, it is also small at 7MB when compressed.
docker run -d -p 5335:5335/tcp -p 5335:5335/udp --name unbound owenelliottdev/unbound:latestservices:
unbound:
container_name: unbound
image: owenelliottdev/unbound:latest
ports:
- "5335:5335/tcp"
- "5335:5335/udp"
restart: unless-stoppedDon't expose 5335 to the public internet, if you expose 5335 to the internet then you are vulerable to cache snooping and DNS amplification attacks.
If you want to harden the docker configuration you can run it on an internal docker network to only expose it to services which need it as oppose to sharing it with the entire LAN.
Using a bridge network allows you to limit access to specific containers on that network:
services:
unbound:
container_name: unbound
image: owenelliottdev/unbound:latest
restart: unless-stopped
networks:
- unbound_dns
networks:
unbound_dns:
driver: bridgeYou can run unbound as a DNS server for Pi-Hole in Docker as follows:
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
networks: # Addition of networks to the typical Pi-Hole compose
- unbound_dns
- default
ports:
- "53:53/tcp"
- "53:53/udp"
- "80:80/tcp"
- "443:443/tcp"
environment:
TZ: 'Europe/London'
FTLCONF_webserver_api_password: 'correct horse battery staple'
FTLCONF_dns_listeningMode: 'all'
volumes:
- './etc-pihole:/etc/pihole'
cap_add:
- NET_ADMIN
- SYS_TIME
- SYS_NICE
restart: unless-stopped
unbound:
container_name: unbound
image: owenelliottdev/unbound:latest
networks:
- unbound_dns
restart: unless-stopped
networks:
unbound_dns:
driver: bridgeThis isolates the network for unbound so you don't risk exposing it to anything other than services on the unbound_dns network, pihole functions as normal.
Set your DNS in the Pi-Hole admin console to unbound#5335.
More details on the Pi-Hole docker compose can be found here.
There are a number of environment variables which can be customised in your docker run command or docker compose. Note that the defaults are not targeted towards small Raspberry Pi's, you may want to take influence from the recommended configuration for Pi-Hole to optimise performance.
-
UNBOUND_NUM_THREADS=8Specifies the number of threads Unbound will use to handle queries. Recommendation: Set based on the number of CPU cores and expected query load. More threads can increase throughput but may increase memory usage. -
UNBOUND_MSG_CACHE_SIZE=125mSets the size of the message cache, which stores raw query responses to improve performance for repeated queries. Recommendation: Larger cache sizes can reduce query latency but use more memory. -
UNBOUND_RRSET_CACHE_SIZE=250mDetermines the size of the RRset (resource record set) cache. This cache holds DNS records for faster future resolution. Recommendation: Increase cache size for high-traffic environments. -
UNBOUND_OUTGOING_RANGE=8192Defines the number of outgoing sockets available for concurrent upstream queries. Recommendation: Higher values improve parallel resolution but consume more file descriptors.
-
UNBOUND_PREFETCH=yesEnables prefetching of popular or expiring cache entries to reduce latency for frequently accessed domains. Recommendation: Useful in high-traffic environments to improve response times. -
UNBOUND_DO_IP6=yesEnables IPv6 resolution in addition to IPv4. Recommendation: Keep enabled if your network supports IPv6. -
UNBOUND_PREFETCH_KEY=yesPrefetches DNSSEC keys before they expire to reduce validation delays. Recommendation: Useful when DNSSEC is in use. -
UNBOUND_EDNS_BUFFER_SIZE=1232Sets the EDNS buffer size for UDP DNS messages. This defines the maximum packet size Unbound can send or receive over UDP. Recommendation: Adjust for networks with MTU constraints; default is usually 1232–4096 bytes. -
UNBOUND_SO_REUSEPORT=yesEnables SO_REUSEPORT socket option to allow multiple threads to bind to the same port efficiently. Recommendation: Improves multi-threaded performance on high-load systems.
-
UNBOUND_CACHE_MAX_TTL=86400Maximum TTL (in seconds) for cached records. Records are discarded after this period. Recommendation: Set according to caching policies; 86400 seconds = 1 day. -
UNBOUND_CACHE_MIN_TTL=300Minimum TTL (in seconds) for cached records. Records with shorter TTLs are retained for at least this period. Recommendation: Ensures frequently queried domains remain in cache for a minimum duration.
docker build -t unbound .
docker run -d -p 5335:5335/tcp -p 5335:5335/udp --name unbound unbound