wg-ui is a WireGuard management service with:
- embedded web UI
- GraphQL API
- single Go binary deployment
- Import and manage existing WireGuard interfaces
- Manage multiple servers/interfaces and peers
- Multi-user auth with JWT sessions
- Automatic interface stats updates (
rxBytes/txBytes) - Works with different WireGuard backends (kernel, NetworkManager, exec)
- Deploy as a binary, package, or OCI container
Backends are configured by URL scheme.
| Driver | OS | URL example | Privileges / requirements |
|---|---|---|---|
linux |
Linux | linux:///etc/wireguard |
Needs CAP_NET_ADMIN (typically run as root) to create/configure interfaces directly via kernel APIs |
networkmanager |
Linux | networkmanager:/// |
Needs access to NetworkManager system DBus operations (typically root or polkit-authorized service user) |
exec |
Linux, macOS | exec:///etc/wireguard?sudo=true |
Uses wg / wg-quick and files under the configured path; with sudo=true it requires passwordless sudo for backend commands |
routeros |
Any OS (network reachability required) | routeros://admin:secret@192.168.88.1:443/rest?insecureSkipVerify=true |
Uses RouterOS REST API over HTTPS to manage WireGuard interfaces and peers |
exec is useful when you want behavior close to native WireGuard CLI tooling.
If the app does not run as root, set:
exec:///etc/wireguard?sudo=true
sudo=true is non-interactive, so passwordless sudo (NOPASSWD) is required for invoked commands.
- Linux commands:
wg,wg-quick,ip, plus file operations needed for config management. - macOS commands:
wg,wg-quick,ifconfig,route,netstat, plus file operations needed for config management.
routeros URL format:
routeros://user:password@host:port/rest
Supported query parameters:
insecureSkipVerify=trueto ignore self-signed/invalid TLS certificates.
RouterOS backend always uses HTTPS REST API endpoints.
Download a release from Releases or build locally:
go build -o wg-ui .Initialize config and run:
# 1) Copy default config
cp .env.dist .env
# 2) Generate JWT secret and set it in .env (GNU/BSD sed compatible)
JWT_SECRET="$(openssl rand -base64 64 | tr -d '\n')"
sed -i.bak "s|^WG_UI_JWT_SECRET=.*|WG_UI_JWT_SECRET=${JWT_SECRET}|" .env && rm -f .env.bak
# 3) Start wg-ui with env vars from .env
set -a
. ./.env
set +a
./wg-uiDefault endpoints:
- App/UI:
http://127.0.0.1:4580 - GraphQL:
http://127.0.0.1:4580/query - Health:
http://127.0.0.1:4580/health
# Download compose + env files
wget https://raw.githubusercontent.com/UnAfraid/wg-ui/master/docker-compose.yaml
wget -O .env https://raw.githubusercontent.com/UnAfraid/wg-ui/master/.env.dist
# Set JWT secret
JWT_SECRET="$(openssl rand -base64 64 | tr -d '\n')"
sed -i.bak "s|^WG_UI_JWT_SECRET=.*|WG_UI_JWT_SECRET=${JWT_SECRET}|" .env && rm -f .env.bak
# Start
docker compose up -dDebian/Ubuntu:
sudo dpkg -i wg-ui_*_linux_amd64.deb
# or
sudo dpkg -i wg-ui_*_linux_arm64.debArch Linux:
sudo pacman -U --noconfirm wg-ui_*_linux_amd64.pkg.tar.zst
# or
sudo pacman -U --noconfirm wg-ui_*_linux_arm64.pkg.tar.zstUse .env.dist as the base. Important values:
WG_UI_JWT_SECRETWG_UI_HTTP_SERVER_HOSTWG_UI_HTTP_SERVER_PORTWG_UI_BOLT_DB_PATHWG_UI_INITIAL_EMAILWG_UI_INITIAL_PASSWORD
See .env.dist for full configuration and defaults.