Manage WireGuard Like a Pro: Deploy wg-easy on Docker for Your HomeLab

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

The Problem: Why Manual Configs Are a Headache

WireGuard has rapidly replaced older protocols like IPsec and OpenVPN because it is incredibly efficient. On a Raspberry Pi 4, for instance, WireGuard can often push 600-800 Mbps of encrypted traffic, while OpenVPN might struggle to hit 100 Mbps. But there is a catch: managing it via the command line is tedious. Manually generating key pairs, writing .conf files for every new phone or laptop, and securely moving those files around feels like a chore from 1995.

HomeLab enthusiasts need security that doesn’t feel like a second job. That is where wg-easy steps in. It packages WireGuard into a single Docker container and adds a clean, responsive web dashboard. Instead of editing text files, you click a button, name your device, and scan a QR code. I have transitioned several setups to this method, and the stability has been rock-solid, even with dozens of active peers.

By using wg-easy, you keep total control of your data while gaining the user-friendly experience of a commercial VPN provider.

Installation: Setting Up Your Docker Environment

Before pulling the image, ensure your host (Ubuntu, Debian, or even a NAS) has Docker and Docker Compose ready. You will also need a public IP or a Dynamic DNS (DDNS) address so your devices can find their way home from the outside world.

1. Open the Gates (Port Forwarding)

WireGuard communicates via UDP. You must log into your router and forward UDP port 51820 to your server’s internal IP. If you skip this, your clients will send packets into the void, and the “handshake” will never happen.

2. The Docker Compose Setup

Organization is key for a clean HomeLab. Start by creating a dedicated folder to house your configuration and keys.

mkdir ~/wireguard-vpn && cd ~/wireguard-vpn
nano docker-compose.yml

Copy and paste the configuration below. This setup uses the official wg-easy image and grants the container the necessary permissions to manage network traffic.

services:
  wg-easy:
    environment:
      # REQUIRED: Your public IP or DDNS (e.g., home.yourdomain.com)
      - WG_HOST=vpn.yourdomain.com
      
      # REQUIRED: A strong password for the dashboard
      - PASSWORD=UseSomethingStrong123!
      
      # OPTIONAL: Point this to Pi-hole or AdGuard for ad-blocking
      # - WG_DEFAULT_DNS=192.168.1.10
      
      - PORT=51821
      - WG_PORT=51820
    image: ghcr.io/wg-easy/wg-easy
    container_name: wg-easy
    volumes:
      - ./config:/etc/wireguard
    ports:
      - "51820:51820/udp"
      - "51821:51821/tcp"
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv4.ip_forward=1

3. Fire It Up

With the file saved, start the service. Docker will pull the image and configure the virtual network interfaces automatically.

docker compose up -d

Configuration: Getting the Details Right

The container is running, but a few small tweaks will ensure a smooth experience. Most connection issues stem from a misconfigured WG_HOST variable.

The Importance of WG_HOST

This variable tells your clients where to connect. If you use a local IP like 192.168.1.50, your VPN will only work while you are sitting in your living room. Use a public IP or a service like DuckDNS. This ensures your phone can find the server whether you are at a coffee shop or in another country.

Hardening the Web UI

The web interface is convenient, but it is also a target. Never leave the PASSWORD field blank. For those seeking extra credit, place this UI behind a reverse proxy like Nginx Proxy Manager. Adding an SSL certificate ensures your admin credentials aren’t sent over the internet in plain text.

A Note on Kernel Modules

WireGuard lives inside the Linux kernel for maximum speed. If the container fails to start, your host might be missing the necessary headers. On most modern Linux distros, a quick update fixes this:

sudo apt update && sudo apt install wireguard

Connecting Your First Device

Now for the best part. Navigate to http://your-server-ip:51821 in your browser and log in. The interface is refreshingly simple.

Adding a Peer

  1. Click “+ New Client”.
  2. Name it something specific like “Pixel-7-Pro” or “MacBook-Air”.
  3. Hit “Create”.

A new entry will appear instantly. To connect a phone, click the QR Code icon and scan it using the WireGuard app. For laptops, simply download the .conf file and import it into the WireGuard client. It takes less than 10 seconds.

Real-Time Monitoring

The wg-easy dashboard is more than just a setup tool. It shows you exactly who is connected with a green status indicator. You can also monitor data transfer—handy for spotting a background backup process that is eating your home upload bandwidth.

Split Tunnel vs. Full Tunnel

By default, wg-easy routes all your phone’s traffic (0.0.0.0/0) through the VPN. This is perfect for security on public Wi-Fi. However, if you only want to access your HomeLab (like a NAS at 192.168.1.100) while using your current location’s internet for Netflix, change the “Allowed IPs” in the client app to your home subnet (e.g., 192.168.1.0/24).

Since switching to this Docker-based workflow, I haven’t touched a config file in months. It just works. You get the raw speed of the kernel-level protocol with the convenience of a modern web app.

Share: