Wg-Easy (WireGuard-easy) is an open-source web UI for managing WireGuard VPN configurations, clients, and connections — no manual wg CLI config editing needed. This guide installs it via Docker on Ubuntu 24.04, secures the management UI behind Nginx Proxy Manager with Let's Encrypt TLS, and connects a WireGuard client.
Prerequisites: an Ubuntu 24.04 instance, non-root sudo user, a domain A record (e.g.
wg-easy.example.com), Docker + Docker Compose.
Install Wg-Easy
1. Confirm Docker is running, add yourself to the docker group:
$ sudo service docker status
If missing: sudo apt install docker.io docker-compose. If inactive: sudo service docker start.
$ whoami
$ sudo usermod -aG docker linuxuser
$ exec su - $USER
2. Generate a bcrypt-hashed admin password:
$ htpasswd -nbB admin strongpassword
Copy the admin:$2y$... output.
Option A: Docker CLI
$ docker pull ghcr.io/wg-easy/wg-easy
$ docker run --detach \
--name wg-easy \
--env LANG=en \
--env WG_HOST=wg-easy.example.com \
--env PASSWORD_HASH='$2y$05$ROESp.kfeIwWHyRkVOXXEu/xKCXq03hTRxr4Y8ppxj6jtaiEuJ7Su' \
--env PORT=51821 \
--env WG_PORT=51820 \
--volume ~/.wg-easy:/etc/wireguard \
--publish 51820:51820/udp \
--publish 51821:51821/tcp \
--cap-add NET_ADMIN \
--cap-add SYS_MODULE \
--sysctl 'net.ipv4.conf.all.src_valid_mark=1' \
--sysctl 'net.ipv4.ip_forward=1' \
--restart unless-stopped \
ghcr.io/wg-easy/wg-easy
Replace WG_HOST and PASSWORD_HASH with your domain and generated hash. net.ipv4.ip_forward=1 is what lets clients route their traffic through the server.
$ docker ps
Option B: Docker Compose
$ cd
$ nano wg-easy.yml
volumes:
etc_wireguard:
services:
wg-easy:
environment:
- LANG=en
- WG_HOST=wg-easy.example.com
- PASSWORD_HASH=$2y$05$ROESp.kfeIwWHyRkVOXXEu/xKCXq03hTRxr4Y8ppxj6jtaiEuJ7Su
- PORT=51821
- WG_PORT=51820
- WG_CONFIG_PORT=92820
image: ghcr.io/wg-easy/wg-easy
container_name: wg-easy
volumes:
- etc_wireguard:/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
$ docker-compose -f wg-easy.yml up -d
$ docker ps
Secure the Web UI with Nginx Proxy Manager
$ nano nginx-proxy.yml
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-man
restart: unless-stopped
ports:
- '80:80'
- '443:443'
- '81:81'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
$ docker-compose -f nginx-proxy.yml up -d
$ docker ps
Connect both containers on a shared network:
$ docker network create wg-easy
$ docker network ls
$ docker network connect wg-easy nginx-proxy-man
$ docker network connect wg-easy wg-easy
Configure the Reverse Proxy
$ sudo ufw allow 80,443,81/tcp
$ sudo ufw reload
- Visit
http://SERVER-IP:81, log in with the defaultadmin@example.com/changeme— change these immediately. -
Hosts → Proxy Hosts → Add Proxy Host: your domain, scheme
http, forward hostnamewg-easy, forward port51821. - Enable Block Common Exploits and Websockets Support, keep Access List Publicly Accessible.
- SSL tab → Request a new SSL Certificate with Let's Encrypt, enter your email, agree to terms, Save.
- Click your domain in the Proxy Hosts list to confirm the Wg-Easy login page loads over HTTPS.
Access Wg-Easy and Create a Client
- Visit
https://wg-easy.example.com, log in with the password you hashed earlier. - New Client → name it → Create.
-
Download Configuration for the client
.conffile, or use QR Code for mobile clients.
Connect a WireGuard Client
- Download the WireGuard client for your OS.
- Open it → Manage Tunnels → Add Tunnel → Import Tunnel(s) from File → select the downloaded config.
- Activate the new tunnel.
- Confirm the connection is active, then check
https://wg-easy.example.comfor live network stats on that client.
Next Steps
Wg-Easy is running with TLS-secured admin access and at least one connected client. From here:
- Create separate clients per device/user for individual traffic tracking
- Disable clients temporarily from the UI instead of deleting them when access needs to pause
- Integrate with existing WireGuard configs if you're migrating from a manually-managed setup
For the full guide, visit the original article on Vultr Docs.
Top comments (1)
handy ui. i'd still keep the admin panel off the public internet and only reach it over the tunnel, plus pin the image digest. after adding a peer, check handshake counters and try a lower mtu if big transfers stall.