Deployment Guide

From zero to a working WireGuard VPN admin panel in under five minutes.

Prerequisites

  • A Linux server reachable from where you’ll manage it
  • Docker and Docker Compose installed
  • A domain name pointing to your server’s IP
  • Ports 80 and 443 open for Caddy; your WireGuard UDP port open (default 51820)

Caddy requires a valid DNS name — either internal or public — pointing to your server so it can obtain and renew SSL certificates automatically.


Deploy

mkdir wireguard_webadmin && cd wireguard_webadmin
wget -O docker-compose.yml \
  https://raw.githubusercontent.com/eduardogsilva/wireguard_webadmin/main/docker-compose-caddy.yml

Create a .env file in the same directory. Set SERVER_ADDRESS to your domain:

SERVER_ADDRESS=vpn.example.com
DEBUG_MODE=False
TIMEZONE=America/Sao_Paulo

See the .env reference below for all available variables.

docker compose up -d

Access the panel at https://vpn.example.com. Caddy obtains and renews SSL certificates automatically.


.env reference

Variable Required Description
SERVER_ADDRESS Yes DNS name or IP of your server. Must match what you type in the browser — a mismatch causes CSRF errors.
DEBUG_MODE No Set to True to enable Django debug mode. Never use in production. Default: False.
TIMEZONE No Timezone for the application. Use a value from the tz database. Default: America/Sao_Paulo.
EXTRA_ALLOWED_HOSTS No Additional hostnames Django should accept, comma-separated. SERVER_ADDRESS is always included. Example: app1.example.com,app2.example.com:8443.
WIREGUARD_STATUS_CACHE_ENABLED No Cache WireGuard status to reduce calls to wg. Default: True.
WIREGUARD_STATUS_CACHE_REFRESH_INTERVAL No How often (in seconds) the cache refreshes. Allowed: 30, 60, 150, 300. Default: 60.
WIREGUARD_STATUS_CACHE_WEB_LOAD_PREVIOUS_COUNT No How many cached snapshots to preload on page load (0–9). Higher values pre-populate traffic charts. Lower if the peer list feels slow. Default: 9.
DISABLE_AUTO_APPLY No Disable automatic application of WireGuard and DNS configuration changes. By default, peer and DNS changes are applied immediately. Set to true to apply changes manually. Default: false.
WIREGUARD_MTU No Custom MTU for WireGuard interfaces (server and client configs). Only change if you know what you are doing. Must be an integer between 1280 and 9000. After changing, re-export and redistribute all client configs — mismatched MTU can cause connectivity issues. Default: 1420.
VPN_CLIENTS_CAN_ACCESS_DJANGO No Allow VPN clients to access the web interface directly via the internal interface at http://ip_or_hostname:8000. When enabled, the internal address including port :8000 must be added to EXTRA_ALLOWED_HOSTS, otherwise Django will block the request. Default: False.

Upgrading

Data is persisted in Docker volumes. Upgrading does not affect your peers, firewall rules, DNS entries, or any other configuration.

01
Navigate to the project directory
cd wireguard_webadmin
02
Stop services and pull latest images
docker compose down
docker compose pull
03
Back up your data
tar cvfz wireguard-webadmin-backup-$(date +%Y-%m-%d-%H%M%S).tar.gz \
  /var/lib/docker/volumes/wireguard_webadmin_wireguard/_data/ \
  /var/lib/docker/volumes/wireguard_webadmin_rrd_data/_data/
04
Update the compose file
wget -O docker-compose.yml \
  https://raw.githubusercontent.com/eduardogsilva/wireguard_webadmin/main/docker-compose-caddy.yml
05
Start the updated stack
docker compose up -d
06
Check logs for unexpected errors
docker compose logs wireguard_webadmin

Troubleshooting

Caddy isn’t getting a certificate

  • Confirm your domain’s A record points to the server’s public IP
  • Verify ports 80 and 443 are open and not blocked upstream
  • Check Caddy logs: docker compose logs caddy

The panel isn’t loading

  • Check all containers are running: docker compose ps
  • Look for errors: docker compose logs wireguard_webadmin
  • Verify SERVER_ADDRESS in .env matches exactly what you’re typing in the browser

CSRF errors on login

SERVER_ADDRESS is misconfigured. It must match the hostname (and port, if non-standard) used to access the panel. Update .env and restart with docker compose up -d.

WireGuard peers can’t connect

  • Confirm the WireGuard UDP port is open on the host firewall. The default is 51820, but if you’re running multiple instances each one needs its own port.
  • Make sure the UDP port range declared in docker-compose.yml matches what is configured in each WireGuard instance inside the panel. A mismatch means the container won’t expose the right port to the host.
  • Verify IP forwarding is enabled on the host: sysctl net.ipv4.ip_forward

What’s running

ServiceRole
wireguard-webadminDjango application — web UI and API
caddyReverse proxy + automatic TLS
auth-gatewayZero Trust authorization layer — enforces identity checks before proxying to upstream
cronScheduled tasks — peer enable/disable, cache refresh
rrdtoolTraffic history — RRD data collection and graphing
dnsdnsmasq-based resolver with category blacklist support