Installation Guide¶
Installation instructions for WireBuddy with Docker Compose, Docker Run or a local development setup.
Installation Methods¶
WireBuddy can be installed in several ways:
| Method | Difficulty | Best For |
|---|---|---|
| Docker Compose | ⭐ Easy | Production, most users |
| Docker Run | ⭐⭐ Moderate | Custom setups |
| Local Development | ⭐⭐⭐ Advanced | Development, testing |
Docker Compose (Recommended)¶
The easiest and most reliable way to run WireBuddy.
1. Install Docker¶
2. Install and start WireBuddy¶
Follow the Quick Start for the sysctl settings (IP forwarding, conntrack accounting), the .env file, the first start and the bootstrap credentials. The Docker Setup guide covers the Compose file, its capabilities and security options, persistent data, health checks and docker run.
Network Mode Host
WireBuddy requires network_mode: host to manage WireGuard interfaces and access conntrack statistics. This is a Linux-specific feature.
Local Development¶
For development or non-Docker deployments.
Prerequisites¶
- Python 3.13+
- pip and venv
- System dependencies:
- WireGuard tools (
wg,wg-quick) - Unbound DNS resolver
- conntrack-tools (optional, for traffic analytics)
1. Install System Dependencies¶
2. Clone Repository¶
3. Create Virtual Environment¶
4. Install Python Dependencies¶
5. Configure Environment¶
Edit .env and set your WIREBUDDY_SECRET_KEY. To enable hot reload, also set:
6. System Configuration¶
Apply the sysctl settings described in the Quick Start:
sudo sysctl -w net.ipv4.conf.all.forwarding=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
sudo sysctl -w net.netfilter.nf_conntrack_acct=1
7. Run WireBuddy¶
Or use uvicorn directly:
For production, keep a single worker:
Do not run the web UI with multiple Uvicorn workers. Startup tasks and authentication state are process-local.
Post-Installation¶
After installation, proceed with:
- First Steps - Initial configuration
- Security Best Practices - Harden your installation
- Configuration - Advanced settings
Updating WireBuddy¶
Reverse Proxy¶
For production use, place WireBuddy behind a reverse proxy with HTTPS.
# Caddyfile (included in repository)
(proxy_common) {
header_up X-Forwarded-Proto https
header_up X-Forwarded-Port 443
transport http {
keepalive 30s
}
}
vpn.example.com {
# Live event streams used by nodes and the admin UI: disable buffering so
# speedtest progress and node events reach users in real time.
@sse path_regexp sse ^(?:/api/nodes/events|/api/wireguard/speedtest/run/stream/[^/]+|/api/nodes/[^/]+/speedtest/stream)$
reverse_proxy @sse localhost:8000 {
import proxy_common
flush_interval -1
}
# Default reverse proxy
reverse_proxy localhost:8000 {
import proxy_common
}
# Compression
encode gzip
# Cache static assets (1 year)
@static path /static/*
header @static Cache-Control "public, max-age=31536000, immutable"
# Security headers
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options nosniff
X-Frame-Options SAMEORIGIN
Referrer-Policy strict-origin-when-cross-origin
-Server
-X-Powered-By
}
# Request body limit
request_body {
max_size 100MB
}
# Logging
log {
output file /var/log/caddy/access.log {
roll_size 10mb
}
}
}
SSE Support for Node Events
The @sse matcher with flush_interval -1 ensures real-time server-sent events work correctly for multi-node deployments.
server {
listen 443 ssl http2;
server_name vpn.example.com;
# SSL Configuration
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options SAMEORIGIN always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
# Request body limit
client_max_body_size 100M;
# SSE endpoint: disable buffering for real-time events
location /api/nodes/events {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_buffering off;
proxy_cache off;
chunked_transfer_encoding off;
}
# Static assets: aggressive caching
location /static/ {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
add_header Cache-Control "public, max-age=31536000, immutable";
}
# Default location
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
}
SSE Support Required
The /api/nodes/events location with proxy_buffering off is essential for real-time node event streaming in multi-node deployments.
# docker-compose.yml labels
labels:
- "traefik.enable=true"
- "traefik.http.routers.wirebuddy.rule=Host(`vpn.example.com`)"
- "traefik.http.routers.wirebuddy.entrypoints=websecure"
- "traefik.http.routers.wirebuddy.tls.certresolver=letsencrypt"
# Security Headers
- "traefik.http.middlewares.wirebuddy-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.wirebuddy-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.wirebuddy-headers.headers.stsPreload=true"
- "traefik.http.middlewares.wirebuddy-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.wirebuddy-headers.headers.frameDeny=true"
- "traefik.http.middlewares.wirebuddy-headers.headers.customResponseHeaders.Referrer-Policy=strict-origin-when-cross-origin"
# Request body limit (100MB for backups)
- "traefik.http.middlewares.wirebuddy-body.buffering.maxRequestBodyBytes=104857600"
# Apply middlewares
- "traefik.http.routers.wirebuddy.middlewares=wirebuddy-headers,wirebuddy-body"
SSE Support
Traefik automatically handles SSE correctly by default. No special configuration needed for /api/nodes/events.
Firewall Configuration¶
If you're running a firewall, you need to allow:
- Port 8000/tcp - Web interface (or your custom port)
- Port 51820/udp - WireGuard (default, adjust per interface)
- Port 53/udp - DNS (if using WireBuddy as DNS server)