WG-Easy
The easiest way to run WireGuard VPN with a web UI
WG-Easy bundles WireGuard with a simple web interface for managing clients, generating QR codes, and monitoring connections. It deploys as a single Docker container.
Key features
- One-container deployment
- Web UI for clients
- QR code generation
- Connection statistics
Pros & cons
Strengths
- Extremely easy setup
- Friendly UI
Trade-offs
- Single WireGuard interface only
WG-Easy replaces
Last reviewed Aug 26, 2026 · 853 words
Ten minutes from an empty VPS to a phone connected over WireGuard, scanned from a QR code. That is the honest time budget for WG-Easy, and nothing else in the remote access category beats it for a plain, self-controlled VPN. The 10 minutes assume one thing WG-Easy cannot do for you: UDP port 51820 must reach the container from the internet. Everything below is arranged around that fact.
The compose file, and the four lines that make it work
services:
wg-easy:
image: ghcr.io/wg-easy/wg-easy:latest
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
volumes:
- ./wg-data:/etc/wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
restart: unless-stopped
Port 51820/udp is WireGuard; 51821/tcp is the web UI. The two capabilities let the container create the interface and load the kernel module, and the two sysctls let it forward traffic. Leave any of those four out and the container starts, the UI works, and no client ever passes traffic, which is the single most common WG-Easy support thread. The host kernel needs WireGuard support, which every mainstream Linux since 2020 has built in.
On first start the web UI walks you through setting the admin password and the public hostname or IP that clients will connect to. Older releases took these as WG_HOST and PASSWORD_HASH environment variables instead; if you are following a tutorial that uses them and the container ignores them, that is why. Whichever style your release uses, that host value is baked into every client config, so set it to a DNS name rather than an IP if the IP might ever change.
The web UI does one job well
Add a client, name it, and the UI shows a QR code for the mobile apps and a downloadable .conf for desktops. It displays each peer's last handshake and transfer totals, which is enough to see who is connected and who has not been for months. That is essentially the whole feature set, and it is why the catalogue calls this Easy and beginner-friendly. The UI must never be exposed to the internet: bind port 51821 to localhost or a LAN interface, reach it over the VPN itself or a reverse proxy with authentication.
Split tunnel or full tunnel is a one-line choice
By default every client routes all traffic through the VPN, which is what you want on hotel wifi and not what you want at home on a 20 Mbps upload. The setting is the allowed IPs the server hands to clients; set it to your home subnet, say 192.168.1.0/24, plus the VPN subnet, and clients only send LAN-bound traffic through the tunnel. The default DNS handed to clients can also be changed, and pointing it at a Pi-hole on the LAN gives every phone ad blocking on the road, which is the most-used feature of my own setup.
The single-interface limit, and why it rarely matters
The catalogue's one con is that WG-Easy manages a single WireGuard interface. In practice that means one VPN network with one address range, and every client is a peer on it. You cannot, from one WG-Easy, run a separate network for family devices and another for a friend's server with different routing. For a household it does not matter. For a small business that wants segmentation, it is a reason to look at Netbird or a hand-managed WireGuard config instead.
Where Tailscale wins, and where it does not
Tailscale and its self-hosted control server Headscale solve the problem WG-Easy leaves you with: needing a public IP and an open port. They punch through NAT, work from behind CGNAT, and handle device-to-device mesh routing, and the three approaches to remote access post lays out the trade-off in full. WG-Easy wins when you have a public IP and want zero third parties in the loop, when you want the VPN's exit to be your own server so your phone's traffic leaves from your home IP, and when you would rather understand 30 lines of WireGuard than a coordination server. For the OpenVPN Access Server crowd, it is the direct replacement with a fraction of the setup and better throughput.
What I'd do
WG-Easy on the home router's DMZ host or a VPS with a public IP, the compose above, UI bound to localhost, host set to a DNS name. Full tunnel with Pi-hole DNS for phones and laptops, and a second peer with split tunnel for a desktop that only needs the LAN. Behind CGNAT with no way to open a port: Tailscale, no argument. At 128 MB of RAM and 26,000-plus stars of maintenance, WG-Easy is the least surprising VPN you can run, and least surprising is the right property for the thing that gets you into your network from outside.
Compare WG-Easy
4 head-to-head comparisons.
Similar remote access & vpn apps
RustDesk
Remote Access & VPNOpen-source remote desktop alternative to TeamViewer
Replaces TeamViewer, AnyDesk
frp
Remote Access & VPNFast reverse proxy to expose local servers behind NAT
Replaces ngrok
Headscale
Remote Access & VPNOpen-source self-hosted Tailscale control server
Replaces Tailscale
Sunshine
Remote Access & VPNSelf-hosted game-stream host for Moonlight clients
Replaces NVIDIA GameStream, Parsec
Tailscale
Remote Access & VPNZero-config mesh VPN built on WireGuard
Replaces ZeroTier
JumpServer
Remote Access & VPNOpen-source bastion host and PAM platform
Replaces CyberArk, Teleport