Deploy a WireGuard Docker container with wg-easy
When I started using Pi-hole in 2018, I wanted to use Pi-hole filtering on my mobile internet connection, so I added PiVPN to one of my failover Pi-hole devices. Using the WireGuard iOS app and the on-demand setting, every time I left home and my phone disconnected from Wi-Fi, the VPN connected, and I continued using Pi-hole protections on my mobile device.
Since I started fiddling with Docker in mid-2023, I have migrated some of my homelab services, including my UniFi controller and LibreNMS, into Docker containers.
In April 2024, the PiVPN project announced on Reddit that maintenance was ending. Later that same day, I started poking around for an alternative that I could run in Docker. I found that solution in wg-easy.
An example Docker compose file based on my real-world use:
services: wg-easy: dns: - 192.168.21.2 - 192.168.21.3 environment: - PASSWORD=a_g00d_p@assword # web UI password - PORT=5150 # web port - UI_TRAFFIC_STATS=true - WG_DEFAULT_DNS=192.168.21.3,192.168.21.2 - WG_DEVICE=eth0 - WG_HOST=ddnshost.example.net # DDNS hostname - WG_MTU=1420 - WG_PERSISTENT_KEEPALIVE=25 - WG_PORT=51820 # wireguard port image: ghcr.io/wg-easy/wg-easy:latest hostname: wg-easy container_name: wg-easy volumes: - wg-easy_data:/etc/wireguard restart: unless-stopped mem_limit: 125m cap_add: - NET_ADMIN - SYS_MODULE network_mode: host volumes: wg-easy_data: external: true
Additional iptables rules are needed on the Docker host to forward the traffic to the container:
iptables -t nat -A POSTROUTING -o ens192 -j MASQUERADE iptables -A FORWARD -i ens192 -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i wg0 -o ens192 -j ACCEPT # This is useful if you are trying to connect from your LAN # to a device on your LAN via the VPN address (OPTIONAL) iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
The container interface is wg0
and the Docker host interface is ens192
.
I used host networking mode because if I used the ipvlan driver or bridge driver, I couldn't connect to my Docker host after starting the VPN tunnel from my mobile device.
Next, I added a rule to my firewall to send 51820/udp
on the WAN IP to the LAN IP of the Docker host.