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_webadminwget -O docker-compose.yml \
https://raw.githubusercontent.com/eduardogsilva/wireguard_webadmin/main/docker-compose-caddy.ymlCreate a .env file in the same directory. Set SERVER_ADDRESS to your domain:
SERVER_ADDRESS=vpn.example.com
DEBUG_MODE=False
TIMEZONE=America/Sao_PauloSee the .env reference below for all available variables.
docker compose up -dAccess 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. |
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_webadmin02
Stop services and pull latest images
docker compose down
docker compose pull03
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.yml05
Start the updated stack
docker compose up -d06
Check logs for unexpected errors
docker compose logs wireguard_webadminTroubleshooting
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_ADDRESSin.envmatches 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.ymlmatches 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
| Service | Role |
|---|---|
| wireguard-webadmin | Django application — web UI and API |
| caddy | Reverse proxy + automatic TLS |
| auth-gateway | Zero Trust authorization layer — enforces identity checks before proxying to upstream |
| cron | Scheduled tasks — peer enable/disable, cache refresh |
| rrdtool | Traffic history — RRD data collection and graphing |
| dns | dnsmasq-based resolver with category blacklist support |