Skip to content

Docker Setup Guide

WireBuddy's supported container deployment uses Docker host networking on a Linux host. The repository contains the master Compose file at docker/docker-compose.yml and the node Compose file at docker/docker-compose.node.yml.

Prerequisites

  • Linux host (amd64 or arm64)
  • Docker Engine and Docker Compose
  • WireGuard support in the host kernel (Linux 5.6+ or a compatible module)
  • /dev/net/tun
  • IP forwarding enabled on the host

Containers share the host kernel. The image therefore supplies wg and wg-quick, but it cannot supply the WireGuard kernel implementation.

Docker Compose

Clone the repository and create the environment file:

git clone https://github.com/Gill-Bates/wirebuddy.git
cd wirebuddy
cp .env-example .env

Generate a key and store it as WIREBUDDY_SECRET_KEY in .env:

python3 -c "import secrets; print(secrets.token_urlsafe(32))"

The key must contain at least 32 UTF-8 bytes. Keep it unchanged across container recreations; changing or losing it makes encrypted WireGuard and OTP secrets unreadable.

Start WireBuddy from the repository root:

docker compose --env-file .env -f docker/docker-compose.yml up -d

View the startup output, which contains the bootstrap password:

docker compose --env-file .env -f docker/docker-compose.yml logs -f wirebuddy

WireBuddy prints the generated temporary password once to the console, outside the normal log handlers, and never stores it. Find it in the output above.

Open http://<server-ip>:8000 and sign in as admin with that temporary password. The first login requires a password change.

First sign-in is plain HTTP

Until HTTPS is enabled, the bootstrap password and session travel in clear text. Sign in from the host itself, over an SSH tunnel (ssh -L 8000:127.0.0.1:8000 <server>) or from a trusted network.

Why the full Compose command?

The Compose file lives in docker/, while .env lives in the repository root. Passing both paths explicitly makes configuration resolution independent of the current working directory.

Included Compose Security

The supplied Compose service uses:

  • network_mode: host
  • all capabilities dropped, then re-added individually: NET_ADMIN for WireGuard, plus NET_BIND_SERVICE, SETUID, SETGID, CHOWN, and DAC_OVERRIDE for the bundled Unbound resolver
  • no-new-privileges:true
  • /dev/net/tun
  • a 40-second stop grace period
  • bounded JSON-file log rotation
  • a readiness health check against /ready

Do not switch the service to bridge or macvlan networking. WireBuddy verifies host networking at startup because interface management and conntrack statistics require the host network namespace.

WIREBUDDY_SKIP_NETWORK_CHECK=1 is a development/CI escape hatch, not a production setting.

Persistent Data

The Compose file mounts docker/data/ at /app/data in the container.

Path Content
wirebuddy.db Users, interfaces, peers, settings, and node state
certs/ ACME certificates and account material
dns/ Generated Unbound configuration and DNS query data
tsdb/ Traffic, DNS trend, network, and speed-test metrics
geolite2/ Downloaded GeoLite2 City and ASN databases

Back up both docker/data/ and the secret key. The application also provides backup and restore controls under Settings → Backup.

Custom Web Port or Bind Address

The GUI port and localhost-only setting are normally managed under Settings → General → Server Settings and take effect after restart.

Docker deployments can override them in .env. WIREBUDDY_PORT always takes precedence, and the supplied Compose file always sets it (default 8000), so under Compose change the port here rather than in the Settings:

WIREBUDDY_HOST=0.0.0.0
WIREBUDDY_PORT=8080

Because host networking is used, no Docker ports: mapping is required. The selected port must be free on the host.

Reverse Proxy

The Docker entrypoint trusts forwarded headers from loopback by default. For a same-host Caddy or nginx proxy, this needs no configuration. If the proxy connects from another address, set WIREBUDDY_TRUSTED_PROXIES to the exact proxy IP or CIDR — this single variable covers both Uvicorn's forwarded-header trust and the application-level client-IP/HTTPS-cookie detection. A wildcard (*) is rejected.

WIREBUDDY_TRUSTED_PROXIES=192.168.1.10/32
WIREBUDDY_PUBLIC_ORIGIN=https://vpn.example.com

See Environment Variables and the Installation Guide for complete proxy examples.

Docker Run

Compose is recommended. An equivalent basic container can be started with:

docker run -d \
  --name wirebuddy \
  --network host \
  --cap-drop ALL \
  --cap-add NET_ADMIN \
  --cap-add NET_BIND_SERVICE \
  --cap-add SETUID \
  --cap-add SETGID \
  --cap-add CHOWN \
  --cap-add DAC_OVERRIDE \
  --security-opt no-new-privileges:true \
  --stop-timeout 40 \
  --device /dev/net/tun:/dev/net/tun \
  -e TZ=Etc/UTC \
  -e WIREBUDDY_SECRET_KEY="$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" \
  -e WIREBUDDY_DATA_DIR=/app/data \
  -v wirebuddy-data:/app/data \
  --restart always \
  giiibates/wirebuddy:latest

Persist the generated secret separately before relying on this example for a production installation.

Health Checks

Two unauthenticated probes are available:

  • /health: lightweight liveness check
  • /ready: readiness including database, scheduler, and expected DNS ingestion state

The supplied Compose file and the image health check use /ready, so the container is reported unhealthy when the database, the scheduler or the DNS log ingestion stops working. Use /health where you only need to know that the process answers.

Updating

docker compose --env-file .env -f docker/docker-compose.yml pull
docker compose --env-file .env -f docker/docker-compose.yml up -d

Use latest for the current stable release or pin an existing full release tag from Docker Hub.

Managing the Container

# Status
docker compose --env-file .env -f docker/docker-compose.yml ps

# Restart
docker compose --env-file .env -f docker/docker-compose.yml restart wirebuddy

# Shell
docker compose --env-file .env -f docker/docker-compose.yml exec wirebuddy bash

# WireGuard status
docker compose --env-file .env -f docker/docker-compose.yml exec wirebuddy wg show

Remote Node

Remote nodes use docker/docker-compose.node.yml and an enrollment token plus verification key created by the master. Follow the Multi-Node Deployment guide rather than adapting the master Compose service.

Troubleshooting

If the container exits during startup:

docker compose --env-file .env -f docker/docker-compose.yml logs wirebuddy
docker compose --env-file .env -f docker/docker-compose.yml config
docker inspect wirebuddy --format '{{.HostConfig.NetworkMode}}'

The final command must print host. Also verify that /dev/net/tun exists, the configured GUI port is free, and the secret key has at least 32 bytes.

Next Steps