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

VariableRequiredDescription
SERVER_ADDRESSYesDNS name or IP of your server. Must match what you type in the browser — a mismatch causes CSRF errors.
DEBUG_MODENoSet to True to enable Django debug mode. Never use in production. Default: False.
TIMEZONENoTimezone for the application. Use a value from the tz database. Default: America/Sao_Paulo.
EXTRA_ALLOWED_HOSTSNoAdditional hostnames Django should accept, comma-separated. SERVER_ADDRESS is always included. Example: app1.example.com,app2.example.com:8443.
WIREGUARD_STATUS_CACHE_ENABLEDNoCache WireGuard status to reduce calls to wg. Default: True.
WIREGUARD_STATUS_CACHE_REFRESH_INTERVALNoHow often (in seconds) the cache refreshes. Allowed: 30, 60, 150, 300. Default: 60.
WIREGUARD_STATUS_CACHE_WEB_LOAD_PREVIOUS_COUNTNoHow 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.

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