# wg-easy — Self-Hosted WireGuard VPN with Web Admin UI > Deploy a full WireGuard VPN server with an intuitive browser-based dashboard for managing clients, QR codes, and traffic stats. ## Install Save as a script file and run: # wg-easy — Self-Hosted WireGuard VPN with Web Admin UI ## Quick Use ```bash docker run -d --name wg-easy -e WG_HOST=vpn.example.com -e PASSWORD=changeme -v ~/.wg-easy:/etc/wireguard -p 51820:51820/udp -p 51821:51821/tcp --cap-add NET_ADMIN --cap-add SYS_MODULE --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv4.conf.all.src_valid_mark=1 ghcr.io/wg-easy/wg-easy ``` ## Introduction wg-easy wraps the WireGuard kernel module in a clean web interface so anyone can stand up a VPN server in minutes. It removes the usual manual key-generation and iptables steps, letting you add or revoke clients from a browser. ## What wg-easy Does - Provides a responsive web UI for creating, listing, and deleting WireGuard clients - Generates downloadable config files and scannable QR codes for each peer - Displays real-time per-client upload and download traffic statistics - Handles WireGuard key pair generation and DNS configuration automatically - Supports password-protected admin access and optional two-factor authentication ## Architecture Overview wg-easy runs as a single Docker container that bundles a Node.js web server with the WireGuard userspace tools. The container requires NET_ADMIN capability to manage network interfaces and forwards UDP port 51820 for VPN traffic alongside TCP port 51821 for the admin panel. Configuration files are persisted in a mounted volume so peers survive container restarts. ## Self-Hosting & Configuration - Only Docker and a public IP or domain are required; no build step needed - Set WG_HOST to your server's public address and PASSWORD for admin login - Override default DNS, MTU, and allowed IPs via environment variables - Persist /etc/wireguard to a host volume or Docker named volume for durability - Place behind a reverse proxy (Caddy, Traefik, nginx) for TLS on the web UI ## Key Features - One-command Docker deployment with sensible defaults - Browser-based client management with QR code provisioning - Live bandwidth graphs per connected peer - Automatic iptables and forwarding rule management - Lightweight image under 100 MB, minimal resource footprint ## Comparison with Similar Tools - **Firezone** — full-featured with OIDC SSO but heavier to operate - **Subspace** — similar concept, less actively maintained - **Algo** — Ansible-based, no persistent web UI for client management - **Headscale** — Tailscale-compatible control server, mesh-oriented rather than hub-spoke - **Netmaker** — enterprise mesh VPN with more moving parts ## FAQ **Q: Does wg-easy require the WireGuard kernel module on the host?** A: Yes on Linux; the container uses the host kernel module for best performance. On older kernels you can fall back to the wireguard-go userspace implementation. **Q: Can I run wg-easy behind a NAT or CGNAT?** A: You need at least one publicly reachable UDP port (default 51820). If your ISP uses CGNAT, consider a small cloud relay or a tunneling service. **Q: How do I update wg-easy?** A: Pull the latest image and recreate the container; client configs in the mounted volume are preserved across upgrades. **Q: Is IPv6 supported?** A: Yes. Set WG_DEFAULT_ADDRESS to an IPv6 range and add the appropriate ALLOWED_IPS to enable dual-stack tunneling. ## Sources - https://github.com/wg-easy/wg-easy - https://github.com/wg-easy/wg-easy#readme --- Source: https://tokrepo.com/en/workflows/407704d5-3f97-11f1-9bc6-00163e2b0d79 Author: Script Depot