DEV Community

Cover image for Installing Wg-Easy – An Open-Source Web UI for WireGuard VPN
Sanskriti Harmukh for Vultr

Posted on with Aashish Chaurasiya Originally published at docs.vultr.com

Installing Wg-Easy – An Open-Source Web UI for WireGuard VPN

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
Enter fullscreen mode Exit fullscreen mode

If missing: sudo apt install docker.io docker-compose. If inactive: sudo service docker start.

$ whoami
$ sudo usermod -aG docker linuxuser
$ exec su - $USER
Enter fullscreen mode Exit fullscreen mode

2. Generate a bcrypt-hashed admin password:

$ htpasswd -nbB admin strongpassword
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Option B: Docker Compose

$ cd
$ nano wg-easy.yml
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
$ docker-compose -f wg-easy.yml up -d
$ docker ps
Enter fullscreen mode Exit fullscreen mode

Secure the Web UI with Nginx Proxy Manager

$ nano nginx-proxy.yml
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
$ docker-compose -f nginx-proxy.yml up -d
$ docker ps
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Configure the Reverse Proxy

$ sudo ufw allow 80,443,81/tcp
$ sudo ufw reload
Enter fullscreen mode Exit fullscreen mode
  1. Visit http://SERVER-IP:81, log in with the default admin@example.com / changeme — change these immediately.
  2. Hosts → Proxy Hosts → Add Proxy Host: your domain, scheme http, forward hostname wg-easy, forward port 51821.
  3. Enable Block Common Exploits and Websockets Support, keep Access List Publicly Accessible.
  4. SSL tab → Request a new SSL Certificate with Let's Encrypt, enter your email, agree to terms, Save.
  5. 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

  1. Visit https://wg-easy.example.com, log in with the password you hashed earlier.
  2. New Client → name it → Create.
  3. Download Configuration for the client .conf file, or use QR Code for mobile clients.

Connect a WireGuard Client

  1. Download the WireGuard client for your OS.
  2. Open it → Manage TunnelsAdd Tunnel → Import Tunnel(s) from File → select the downloaded config.
  3. Activate the new tunnel.
  4. Confirm the connection is active, then check https://wg-easy.example.com for 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 (0)