Files
ihasvpn/docker-compose.yml
T
jcoffey 6c006e1d4d WireGuard server with an embedded admin console
Go backend that drives kernel WireGuard over netlink (wireguard-go as the
fallback), nftables NAT with MSS clamping, forwarding and buffer sysctls,
SQLite for peers, users, sessions, traffic history and the audit log.

React console: dashboard with live rates and usage history, peer management
with QR codes and .conf downloads, disconnect, session reset, key rotation,
expiry, client-supplied keys, settings, users with admin and viewer roles,
two-factor authentication with recovery codes, audit log.

Docker image on Alpine with compose files for bridged and host networking,
CI and GHCR publish workflows, performance notes.
2026-09-12 19:56:08 -07:00

56 lines
2.2 KiB
YAML

# WGX: a WireGuard server with a web admin UI, in one container.
#
# Start it, open http://<host>:51821, create the first administrator, add a
# peer, scan the QR code. The container needs NET_ADMIN to create the tunnel
# interface and its NAT rules, and the sysctls below to forward packets.
#
# For the highest throughput see docs/performance.md: it explains when to use
# docker-compose.host.yml (host networking) and which host sysctls matter.
services:
wgx:
image: ghcr.io/coffey-labs/wgx:latest
container_name: wgx
restart: unless-stopped
cap_add:
- NET_ADMIN
# Only needed if the host has not loaded the wireguard module yet and
# you want the container to load it. Usually unnecessary on any kernel
# from 5.6 on: the module loads itself when the interface is created.
# - SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
# Loose reverse-path filtering; strict drops replies arriving on the
# tunnel. WGX would set this itself but /proc/sys is read-only in a
# container, so it has to come from here.
- net.ipv4.conf.all.rp_filter=2
- net.ipv4.conf.default.rp_filter=2
# Uncomment with WGX_SUBNET6 for IPv6 inside the tunnel.
# - net.ipv6.conf.all.forwarding=1
# - net.ipv6.conf.all.disable_ipv6=0
environment:
# The public hostname or IP clients connect to. Asked for at setup too.
WGX_ENDPOINT: vpn.example.com
# UDP port WireGuard listens on; must match the port mapping.
WGX_PORT: "51820"
# Tunnel network. The server takes the first address.
WGX_SUBNET: 10.8.0.0/24
# WGX_SUBNET6: fd42:42:42::/64
# DNS handed to clients by default.
WGX_DNS: 1.1.1.1, 1.0.0.1
# Admin UI. Put a TLS-terminating proxy in front of it, or enable the
# built-in self-signed certificate, before exposing it anywhere but
# localhost or your LAN.
WGX_HTTP_LISTEN: ":51821"
# WGX_TLS_SELF_SIGNED: "true"
# WGX_TRUSTED_PROXIES: 172.16.0.0/12
# WGX_METRICS_TOKEN: change-me
ports:
- "51820:51820/udp"
- "127.0.0.1:51821:51821/tcp"
volumes:
- wgx-data:/data
volumes:
wgx-data: