How To Route Your Docker Containers Through a VPN (Gluetun Guide)

Docker is an incredibly convenient tool for self-hosting your favorite applications. But what if you just want one of your containers routed through a VPN and not all? Here's the easiest way to do just that.

Publish date: 12/18/2023

Docker is a powerful tool used by many (both businesses and hobbyists) because of its convenient nature. Anyone could figure out and use Docker to self-host their favorite applications.

Docker all centers around the concept of "containers". A container is a lightweight, standalone, executable package that includes everything needed to run an application: code, libraries, etc.

Docker containers are isolated from each other and the host system, yet can communicate with each other. You can use this for your advantage.

That said, people use Docker for many types of applications. On one end you have B2B enterprise apps like Nextcloud, and on the other end you have torrenting clients like Deluge.

For one reason or another

There are reasons why you might want to use a VPN with your favorite applications (especially for reasons like seeding Linux ISOs)...

But you might not want to route all of your servers' traffic through a VPN. Just one or a few specified applications.

You could have remote desktop access enabled that you don't want to interfere with. You could have a website running on the server already, etc.

For whatever reason, you don't want to route your entire server through any given VPN.

That's where a tool like Gluetun comes in

Gluetun is a free and open source project that describes themselves as a "lightweight swiss-knife-like VPN client to multiple VPN service providers."

Gluetun logo

Gluetun allows you to tunnel any given Docker container through a VPN -- while the rest of your server remains publicly available as usual.

It officially supports: AirVPN, Cyberghost, ExpressVPN, FastestVPN, HideMyAss, IPVanish, IVPN, Mullvad, NordVPN, Perfect Privacy, Privado, Private Internet Access, PrivateVPN, ProtonVPN, PureVPN, SlickVPN, Surfshark, TorGuard, VPNSecure.me, VPNUnlimited, Vyprvpn, WeVPN, and Windscribe.

But it also supports OpenVPN and WireGuard in general as well. That means you'll be able to use Gluetun with just about any VPN. Paid, or self-hosted on another server.

Let me show you how:

Obtaining your VPN configuration file

To accomplish this, we'll be using Docker Compose. If you're not familiar, the main difference is that Docker Compose reads configuration data from a YAML file.

Docker Compose allows you to run several production based applications concurrently on the same server with ease with the same Docker convenience that you're used to.

Now, like I said earlier, Gluetun supports several VPNs, including any OpenVPN or WireGuard VPN altogether.

So, depending on your VPN setup, this could slightly vary, but you'll get the idea, regardless. Gluetun also documents many different setup situations here as well.

In my case, I use Windscribe as my VPN. It's cheap and simply works, plus has servers throughout the world -- including servers that work on Netflix, etc.

Also, WireGuard is my preferred standard over OpenVPN, so I'll be using that here as well.

So, in order to set up Gluetun with WireGuard, we'll need to obtain our WireGuard configuration file. If you self-host your own VPN, it's incredibly easy to obtain this. If you pay for a VPN, nearly all VPN providers will allow you to export this.

For example, on Windscribe, you can export it here. We can test if our WireGuard configuration file works very easily by spinning up Docker with the following command:

# Wireguard
docker run -it --rm --cap-add=NET_ADMIN -e VPN_SERVICE_PROVIDER=windscribe \
-e VPN_TYPE=wireguard \
-e WIREGUARD_PRIVATE_KEY=wOEI9rqqbDwnN8/Bpp22sVz48T71vJ4fYmFWujulwUU= \
-e WIREGUARD_ADDRESSES="10.64.222.21/32" \
-e WIREGUARD_PRESHARED_KEY= \
-e VPN_ENDPOINT_PORT=80 \
-e SERVER_REGIONS=Netherlands qmcgaw/gluetun

Obviously, edit the according information to fit your own WireGuard configuration file (including the proper VPN port, in my case I selected 80).

Also, you don't need the server region if you're using your own self-hosted WireGuard VPN (and your own configuration file). That's for Windscribe specifically.

After running Docker, we see this:

WireGuard and Windscribe

That means our connection was successful, and our WireGuard configuration file is indeed functional. Take note of what the export looks.

Now we can move forward and setup our docker-compose.yml file since we've verified our configuration is working.

Using Docker Compose

Make sure you've already installed Docker Compose on your server. It's very simple (apt install docker compose on Debian 12, for instance).

Then create a directory for Gluetun to exist inside of:

mkdir glueton

And create the according docker-compose.yml file:

nano docker-compose.yml

Inside should be your same configuration file as so:

version: "3"
services:
  gluetun:
    image: qmcgaw/gluetun
    cap_add:
      - NET_ADMIN
    environment:
      - VPN_SERVICE_PROVIDER=windscribe
      - VPN_TYPE=wireguard
      - WIREGUARD_PRIVATE_KEY=key
      - WIREGUARD_ADDRESSES=192.0.2.2/32
      - VPN_ENDPOINT_PORT=80 \
      - WIREGUARD_PRESHARED_KEY=key 
      - SERVER_REGIONS=Netherlands

Make sure your configuration is right, then close and save the file.

Now run the following command:

docker compose up -d

Congrats! You now have Gluetun successfully running in the background, ready for any Docker container to tunnel traffic through.

Testing that your VPN is working

Your new Docker Compose container should now be running in the background.

If you type docker ps, it will display the name of the Gluetun container. Copy that container name.

Then what you'll do is run the following command:

docker run --rm --network=container:docker_gluetun_1(container name) alpine:3.18 sh -c "apk add wget && wget -qO- https://ipinfo.io"

You should receive back the address of your VPN. In my case, I received back:

  "ip": "X",
  "city": "Amsterdam",
  "region": "North Holland",
  "country": "NL",
  "loc": "52.3710,4.9041",
  "org": "Example",
  "postal": "1011",
  "timezone": "Europe/Amsterdam",
  "readme": "https://ipinfo.io/missingauth"

Despite the fact this server is based in the United States. This means everything is working as it should.

Now when running a new Docker container that you want routed through your VPN, you'll simply need to add --network=container:gluetun(or your container name) when using Docker, or network_mode: "container:gluetun(or your container name)" when using Docker Compose. Easy!

Conclusion

Docker has a solution for pretty much everything. This is no exception.

Hopefully, this article helped you out, and you're walking away knowing how to successfully route any given Docker container through a VPN.

That said, if you're looking for a premium and reliable hosting service, then look no further than xTom.

If you're a hobbyist or just starting out and want to test, then our V.PS brand is perfect for you. You can get a very cost effective and reliable KVM VPS all around the world.

On the other end of things, we also provide dedicated servers, transit, and other IT related services.

Basically, what I'm saying here is big or small, our infrastructure is the right fit for you. Just click here to learn more.

Thanks for reading!

P.S. If you have any questions, don't hesitate to reach out.