1. Blog
  2. Manuals

WireGuard with a Web Interface: Installing wg-easy on a VPS

WireGuard with a Web Interface: Installing wg-easy on a VPS

WireGuard is a fast, simple VPN protocol, but managing it from the shell is tedious: every client needs keys and configuration edits. The wg-easy project adds a web panel to WireGuard where a client is created with one button and a device is set up by scanning a QR code.

What you need

  • a VPS running Ubuntu or Debian — the smallest plan is enough;
  • Docker and Docker Compose — see the installation guide;
  • UDP port 51820 open.

Step 1. Installation

Create a directory and download the official Compose file:

mkdir -p ~/wg-easy && cd ~/wg-easy
curl -o docker-compose.yml https://raw.githubusercontent.com/wg-easy/wg-easy/master/docker-compose.yml

The file already contains everything required: the ghcr.io/wg-easy/wg-easy:15 image, a volume for the configuration, the container’s network capabilities and two ports — 51820/udp for the VPN and 51821/tcp for the admin panel.

Step 2. Access to the panel

The panel transmits the administrator password, so by default it only works over HTTPS. There are two options.

Option A: a domain and a reverse proxy (recommended). Point a subdomain such as vpn.example.com at the server and publish port 51821 through Nginx Proxy Manager or Nginx with Certbot. In that case bind the panel port to the loopback address — replace the line in docker-compose.yml:

      - "127.0.0.1:51821:51821/tcp"

Option B: no domain. Allow plain HTTP by adding a variable to the service definition:

    environment:
      - INSECURE=true

This is only for a first look: the password travels in clear text. Do not leave the panel reachable from the internet in this mode — connect to it through an SSH tunnel:

ssh -L 51821:127.0.0.1:51821 root@203.0.113.10

Step 3. Start

docker compose up -d

Open the VPN port in the firewall:

sudo ufw allow 51820/udp

Step 4. First login

Open the panel in a browser. The setup wizard asks you to:

  1. create the administrator account;
  2. enter the Host — the server’s public IP address or domain that clients will connect to;
  3. confirm port 51820.

The Host value goes into every client’s configuration. If it is wrong, clients cannot connect.

Step 5. Add a client

  1. Click New and enter a client name, for example phone.
  2. For a phone, click the QR code icon and scan it with the WireGuard app: + → Scan from QR code.
  3. For a computer, download the configuration file and import it into the WireGuard app: Import tunnel(s) from file.

WireGuard apps exist for Windows, macOS, Linux, Android and iOS. After enabling the tunnel, check your IP address — it should match the server’s.

The panel shows which clients are connected and how much traffic they have transferred. A client can be disabled temporarily with a toggle or deleted — its configuration stops working at once.

Useful settings

The parameters are changed in the admin panel:

  • DNS — the server clients receive. If AdGuard Home runs on the same server, enter its address and ads are blocked on every connected device.
  • Allowed IPs — which addresses a client sends into the tunnel. 0.0.0.0/0, ::/0 routes all traffic through the VPN; for access to an internal network only, enter its subnet.
  • Persistent Keepalive — a value of 25 helps clients behind NAT keep the connection alive.
  • Expiry — a client can be given a date after which access is switched off automatically.

The client configuration parameters are explained in the WireGuard client configuration guide.

Security

  • Enable two-factor authentication in the administrator profile.
  • Do not expose the panel port to the internet without HTTPS.
  • Create a separate client for each device: a lost device is disabled without reconfiguring the rest.
  • Protect the server itself: SSH key login and Fail2Ban.

Updating

cd ~/wg-easy
docker compose pull
docker compose up -d

Client configuration and keys live in the etc_wireguard volume and survive the update.

If a client does not connect

  • No handshake. Check that UDP port 51820 is open in the server firewall and that Host holds the right address.
  • Connected but no internet. Make sure the container runs with the settings from the official Compose file: without sysctls and cap_add, packet forwarding does not work.
  • Sites do not open by name. Check the DNS address in the settings.
  • Container log: docker logs wg-easy.