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_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 |