Hugo Persson

Wireguard with DNS in Docker

Summary

In this guide, I'll show you how I set up a Wireguard server and a DNS server on the same host in my HomeLab. Many users face issues using a local DNS server with Wireguard. I'll explain how to configure Wireguard to access local devices and use a local DNS server like AdGuard Home, with both running in Docker on the same machine.

Guide

For my HomeLab, I attempted to set up a WireGuard server and DNS server on the same host, but it was not working. While using a DNS server like 1.1.1.1 worked, my local DNS server at 192.168.x.x did not. In this article, I will show you how to configure WireGuard to access all your local devices and use a local DNS server like AdGuard Home. The prerequisite is running both the DNS server and WireGuard server in Docker on the same machine. I use AdGuard Home for the DNS server and wg-easy for the WireGuard server, but this setup should work for any DNS server and WireGuard server.

Configuring the DNS Container

Before setting up WireGuard, we need to tweak the DNS server. Both the DNS container and WireGuard must be on the same Docker network. First, create a network with:

Terminal window
docker network create --subnet=172.22.0.0/16 dns

We use the subnet 172.22.0.0/16 here. This could be any subnet, but we need to set a subnet to assign an IPV4 address to our container.

Next, connect the DNS container to this network by defining the network in your docker-compose file:

networks:
dns:
external: true

Then, add the following to your DNS service configuration:

networks:
dns:
ipv4_address: 172.22.0.2 # This will be used to configure our DNS server for clients

Recreate your container with:

Terminal window
docker compose up -d

Configuring WireGuard

Now, set up the wg-easy container.

Create a new directory, like this:

Terminal window
mkdir **WireGuard**

Then, create a docker-compose.yaml file with the following content:

networks:
dns:
external: true
services:
wg-easy:
environment:
# Change Language:
# (Supports: en, ua, ru, tr, no, pl, fr, de, ca, es, ko, vi, nl, is, pt, chs, cht, it, th, hi)
- LANG=en
# ⚠️ Required:
# Change this to your host's public address
- WG_HOST=wireguard.evercode.se
# Optional:
# - PASSWORD=foobar123
# - PORT=51821
# - WG_PORT=51820
# - WG_DEFAULT_ADDRESS=10.8.0.x
- WG_DEFAULT_DNS=172.22.0.2 # This is the DNS defined earlier
- WG_MTU=1384
- WG_ALLOWED_IPS=0.0.0.0/0, 192.168.50.0/24, 172.22.0.0/16
- WG_PERSISTENT_KEEPALIVE=24
# - WG_PRE_UP=echo "Pre Up" > /etc/wireguard/pre-up.txt
# - WG_POST_UP=echo "Post Up" > /etc/wireguard/post-up.txt
# - WG_PRE_DOWN=echo "Pre Down" > /etc/wireguard/pre-down.txt
# - WG_POST_DOWN=echo "Post Down" > /etc/wireguard/post-down.txt
- UI_TRAFFIC_STATS=true
- UI_CHART_TYPE=2 # (0 Charts disabled, 1 # Line chart, 2 # Area chart, 3 # Bar chart)
image: ghcr.io/wg-easy/wg-easy
container_name: wg-easy
networks:
dns:
ipv4_address: 172.22.0.3
volumes:
- ./config:/etc/wireguard
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1

Recreate your container with:

Terminal window
docker compose up -d

For information on configuring clients and more details, refer to the official documentation: https://github.com/wg-easy/wg-easy/blob/master/README.md.