Skip to main content

How to connect Docker containers across multiple hosts with WireGuard

· 17 min read
Pasha Sviderski
Creator of Uncloud

You want your Docker containers to talk to each other, but they're running on different machines. Perhaps across different cloud providers or mixing cloud with on-prem. The usual approach of mapping services to host ports quickly becomes a pain. Worse, if they're on the public internet, you need to secure every exposed endpoint with TLS and auth.

What if your containers on different machines could communicate directly without exposing any ports? Using their private Docker IPs, as if they were on the same machine. Here's how you can use pure WireGuard and some clever networking tricks to make this work.

What we're building

Docker containers are typically connected to a bridge network on their host machine, which allows them to communicate with each other. A bridge network also provides isolation from containers not connected to it and other networks on the host. What we want to achieve is connecting these bridge networks across machines so that containers on different machines can communicate as if they were connected to the same local bridge network.

The incantation we need is called a site-to-site VPN. Any solution would work. Moreover, if the machines are on the same local network, they're already connected and only lack the appropriate routing configuration. But I'll describe a more versatile approach that works even when the machines are on different continents or behind NAT. WireGuard is the ideal solution for this use case: it's lightweight, fast, simple to configure, provides strong security and NAT traversal.

We'll create a new Docker bridge network multi-host on each machine with unique subnets. Then establish a secure WireGuard tunnel between the machines and configure IP routing so that multi-host bridge networks become routable via the tunnel. Finally, we'll run containers on each machine connected to the multi-host network and test that they can communicate with each other using their private IPs.

I will use these two machines:

  • Machine 1: Debian 12 virtual machine in my homelab network in Australia, which is behind NAT
  • Machine 2: Ubuntu 24.04 server from Hetzner in Finland that has a public IP

WireGuard overlay network