WireGuard with Docker
This tutorial shows how to bring up the ISP side of the WireGuard VPN in a Docker container, using the linuxserver/wireguard image, after having created the VPN in Cpehub.
Prerequisites
Check off items as you confirm them — this is just a visual aid, so reloading the page unchecks everything again.
- The VPN has already been created in Cpehub (you have Cpehub's public key, endpoint, and tunnel IPs).
- Docker and Docker Compose installed on the host.
- The host has access to the ISP's internal networks (OLTs).
1. Structure
wireguard-cpehub/
├── docker-compose.yml
└── config/
└── wg_confs/
└── wg-cpehub.conf
2. docker-compose.yml
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard-cpehub
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- TZ=America/Sao_Paulo
volumes:
- ./config:/config
- /lib/modules:/lib/modules
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
restart: unless-stopped
# Use host network if the container needs to route to the ISP's LAN:
# network_mode: host
3. config/wg_confs/wg-cpehub.conf
[Interface]
PrivateKey = <YOUR_PRIVATE_KEY>
Address = <ISP_TUNNEL_IP>/32
[Peer]
PublicKey = <CPEHUB_PUBLIC_KEY>
Endpoint = <CPEHUB_ENDPOINT>:<PORT>
AllowedIPs = <CPEHUB_NETWORK>/32
PersistentKeepalive = 25
Generate the key pair (if you don't already have one) with:
docker run --rm lscr.io/linuxserver/wireguard:latest sh -c 'wg genkey | tee /dev/stderr | wg pubkey'
The public key goes into the VPN registration in Cpehub; the private key goes into wg-cpehub.conf.
4. Bring up the container
docker compose up -d
5. Verify
docker exec wireguard-cpehub wg show
Look for a recent latest handshake.
Routing to the LAN
For Cpehub to reach the OLTs, the tunnel traffic needs to reach your internal network. In many scenarios you'll need to use network_mode: host (or publish host routes), as well as make sure ip_forward is enabled. Adjust according to your topology.
Common issues
| Symptom | Likely cause | Solution |
|---|---|---|
| No handshake | Wrong endpoint/key or blocked port | Double-check Endpoint, keys, and firewall |
| Handshake OK but can't reach the OLT | Container isn't routing to the LAN | Use network_mode: host / adjust routes |
Missing SYS_MODULE/module | Kernel without the wireguard module | Install wireguard on the host or use a recent kernel |