How to Force Docker Containers Through VPN with Gluetun: Ultimate Security for Torrents & Crawlers

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Set it Up in 5 Minutes: Make Your Containers ‘Invisible’

If you’re looking for a quick solution to route your containers through a VPN without complex network configurations, Gluetun is the top choice. It acts as a sidecar container, wrapping around your application. Here’s the docker-compose template I often use for Surfshark or ProtonVPN (supporting Wireguard for speeds up to 200-300Mbps).

version: "3"
services:
  gluetun:
    image: qmcgaw/gluetun
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    environment:
      - VPN_SERVICE_PROVIDER=surfshark
      - VPN_TYPE=wireguard
      - WIREGUARD_PRIVATE_KEY=YOUR_PRIVATE_KEY
      - SERVER_COUNTRIES=Vietnam
    restart: always

  my-app:
    image: alpine
    container_name: my-app
    network_mode: "service:gluetun" # This line is the key
    command: sh -c "apk add curl && sleep 3600"
    depends_on:
      - gluetun

After running docker compose up -d, verify the result immediately by checking your IP:

docker exec my-app curl ifconfig.me

If a different IP appears instead of your local ISP’s IP, you’ve successfully gone ghost.

Why is Gluetun More Practical Than Installing a VPN on the OS?

Typically, when you enable a VPN on a VPS, all traffic is throttled through the tunnel. This is a nightmare if you’re running Nginx or a Database that requires low latency. Gluetun solves this problem elegantly: it only routes “sensitive” services like Torrent clients or Web Scrapers through the VPN, while letting the rest of the system use the direct connection.

The Network Stack Sharing Mechanism

Gluetun creates a secure tunnel within its container. Thanks to Docker’s network_mode feature, other containers can “attach” themselves to Gluetun’s network. At this point, the application container won’t have its own IP but will share everything with the VPN provider.

All requests from the application are forced through the established tunnel. If the tunnel drops, traffic stops immediately—ensuring total safety.

Notes on Environment Variables

The most common mistake for beginners is the Provider format. Gluetun supports everything from Mullvad and NordVPN to ProtonVPN, but each one requires a specific key declaration style.

  • VPN_SERVICE_PROVIDER: The provider’s name in lowercase (e.g., mullvad).
  • VPN_TYPE: Prioritize wireguard as it’s lightweight and roughly 30% faster than openvpn.
  • WIREGUARD_PRIVATE_KEY: Found in your provided .conf file.

From my experience, when copy-pasting long keys into a YAML file, it’s easy to end up with extra spaces or indentation errors. **To ensure your config file is valid, I usually run the JSON/YAML through toolcraft.app/en/tools/developer/json-formatter to reformat it. It saves a lot of time debugging brackets and indentation.**

Advanced Configuration: Fixing Web UI Access Issues

About 90% of first-time Gluetun users will wonder: “Why is the app running, but I can’t access it via IP:Port in my browser?”.

The Reverse Port Mapping Rule

Since the application container has “borrowed” its network from Gluetun, any ports you want to expose (like port 8080 for qBittorrent) MUST be declared under the gluetun service.

services:
  gluetun:
    ports:
      - 8080:8080 # App ports must be placed here to be accessible
  qbittorrent:
    network_mode: "service:gluetun"

Local Network Access (LAN)

Sometimes Gluetun’s firewall is too restrictive, blocking connections even from your personal machine. If you can’t access the UI, try adding the variable DOT=off to disable DNS over TLS if you encounter hostname resolution conflicts.

To monitor the health of the tunnel, you can enable HTTP_CONTROL_SERVER_ADDRESS: :8000. It provides a small API to check if the VPN is live or down.

Real-world Operational Experience

1. Don’t Forget the Kill Switch

This feature is enabled by default. If the VPN connection drops (due to server maintenance or network lag), Gluetun will immediately disconnect the container’s Internet. This prevents your real IP from leaking—a huge risk when scraping data or downloading torrents.

2. How to Read Logs for Quick Troubleshooting

When the app loses connectivity, don’t guess. Run this command immediately:

docker logs gluetun

If you see an auth failed line, double-check your Private Key. If it says no servers found, it’s likely the country you selected (SERVER_COUNTRIES) doesn’t have servers supporting the Wireguard protocol.

3. Prioritize Singapore/Hong Kong Servers

If your VPS is located in SE Asia, choose a Singapore server to keep ping around 30-50ms. If you get greedy and pick US or European servers, ping can spike over 200ms, making your crawler scripts crawl at a snail’s pace.

4. Optimize DNS to Avoid Resolution Issues

Many ISPs block VPN DNS servers, preventing you from ping google.com even when the tunnel is up. The fastest fix is to force Gluetun to use Cloudflare’s DNS:

- DOT=off
- DNS_ADDRESS=1.1.1.1

Routing Docker through a VPN is actually quite simple once you master the routing mechanism. Good luck with your setup, and if you run into any issues, feel free to leave a comment below!

Share: