Skip to content

WireGuard VPN

WireGuard creates a secure encrypted tunnel between the Azure and Contabo servers. This tunnel is critical — Docker Swarm uses it for all cross-node communication.

PropertyAzure (Leader)Contabo (Reachable)
VPN IP10.10.0.110.10.0.2
Public IP4.180.181.8684.247.134.135
WireGuard port51820/udp51820/udp
Config file/etc/wireguard/wg0.conf/etc/wireguard/wg0.conf
Interfacewg0wg0
Azure (10.10.0.1) ←——— WireGuard Tunnel (UDP 51820) ———→ Contabo (10.10.0.2)
│ │
├── DEV services ├── UAT services
├── Swarm manager ├── Shared services
└── Docker overlay networks ←————————————————————————→ Docker overlay networks
  1. Both servers run WireGuard with pre-shared keys
  2. Traffic between 10.10.0.1 and 10.10.0.2 is encrypted and routed through the tunnel
  3. Docker Swarm overlay networks operate over this tunnel
  4. Services on Azure can reach services on Contabo and vice versa
Terminal window
# View WireGuard status (run on either server)
wg show
# Expected output includes:
# peer: <public key>
# endpoint: <ip>:51820
# latest handshake: X seconds/minutes ago
# transfer: X.XX MiB received, X.XX MiB sent

Key things to check:

  • latest handshake should be recent (within last 2 minutes)
  • transfer should show data flowing in both directions
  • If there’s no handshake or no transfer, the tunnel is likely down
Terminal window
# From Azure, ping Contabo's VPN IP
ping 10.10.0.2
# From Contabo, ping Azure's VPN IP
ping 10.10.0.1
# Test with a timeout
ping -c 3 -W 2 10.10.0.1

If the tunnel is down:

Terminal window
# Restart WireGuard
systemctl restart wg-quick@wg0
# Verify it came back up
wg show
# Test connectivity
ping 10.10.0.1 # or 10.10.0.2

Do this on both servers if the tunnel won’t come up from just one side.

The WireGuard config is at /etc/wireguard/wg0.conf on each server:

# Example structure (Azure side)
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <azure-private-key>
[Peer]
PublicKey = <contabo-public-key>
Endpoint = 84.247.134.135:51820
AllowedIPs = 10.10.0.2/32
PersistentKeepalive = 25
# Example structure (Contabo side)
[Interface]
Address = 10.10.0.2/24
ListenPort = 51820
PrivateKey = <contabo-private-key>
[Peer]
PublicKey = <azure-public-key>
Endpoint = 4.180.181.86:51820
AllowedIPs = 10.10.0.1/32
PersistentKeepalive = 25
  1. Check if WireGuard is running:

    Terminal window
    systemctl status wg-quick@wg0
  2. Check if UDP port 51820 is open:

    Terminal window
    ss -ulnp | grep 51820
  3. Check firewall rules — make sure port 51820/UDP is allowed inbound on both servers

  4. Verify the config file:

    Terminal window
    cat /etc/wireguard/wg0.conf

    Ensure public keys match between peers and endpoints are correct.

  • Check AllowedIPs in the config — they must include the peer’s VPN IP
  • Check if PersistentKeepalive is set (important when behind NAT)
  • Check system routing: ip route | grep 10.10.0

When the WireGuard tunnel goes down:

  • Docker Swarm nodes can’t communicate
  • Services on different nodes can’t reach each other via overlay networks
  • The Swarm may mark the unreachable node as “Down”
  • Services constrained to the unreachable node will show as unhealthy

Recovery: Restart WireGuard on both servers, then verify Swarm node status with docker node ls.