How to Use Gluetun: The Beginner's Guide

CodexFuse Team · 2026-11-02T23:12:00.000Z · 15 min read min read

Gluetun is a Docker container that routes your other containers through a VPN with an always-on killswitch firewall. This beginner guide covers the compose file, the NET_ADMIN rule, attaching qBittorrent, the killswitch test, and port forwarding.

What Is Gluetun, Exactly?

Gluetun is a lightweight Docker container that holds a VPN connection and lets other containers borrow it, so their traffic leaves your network through the VPN tunnel instead of your home IP. Think of it as a network bodyguard: your download client, media grabbers, and scrapers sit behind it, and Gluetun makes sure none of them can ever talk to the internet outside the tunnel. If you are learning how to use Gluetun, that single mental picture — one VPN container, many protected apps — carries you through the whole setup.

Gluetun connects to more than twenty commercial VPN providers, including Mullvad, NordVPN, Private Internet Access, ProtonVPN, Surfshark, AirVPN, and IVPN, over OpenVPN or native WireGuard. It exposes the tunnel to other containers through Docker's network_mode: service:gluetun, and its built-in firewall blocks every packet that tries to leave without the VPN. This guide walks you from zero to a verified killswitch: provider credentials, the compose file, the NET_ADMIN rule, wiring up qBittorrent beginner guide, port forwarding, and the stop-and-curl test that proves the killswitch works. If you want to sanity-check the control server's JSON responses while you follow along, the REST API tester is handy for probing Gluetun's HTTP control server.

What Do You Need Before You Start?

You need three things, and only three: a machine running Docker and Docker Compose, an account with a VPN provider that Gluetun supports, and your provider's credentials. The Docker piece is non-negotiable, so if you have never touched it, read the Docker beginner guide first and come back with Compose installed.

Your VPN account needs working service credentials, not your website login. Most providers issue separate OpenVPN or WireGuard credentials from their account dashboard — NordVPN calls them service credentials, PIA generates them per device, Mullvad hands you an account number plus a WireGuard key. One caution before you pick: Gluetun supports Mullvad over WireGuard only, not OpenVPN. If your heart is set on Mullvad, you are using WireGuard, full stop.

How Do You Write Your First Gluetun Compose File?

You write a single compose.yml with a gluetun service, an .env file holding your secrets, and then bring it up. That is the entire first arc — six steps, and the only "magic" is two Docker settings most beginners have never seen. Follow this order and the tunnel comes up on the first try.

  1. Make a folder for the project, for example ~/gluetun, and inside it create an .env file with your provider credentials. Secrets live here, never committed to git, never pasted into a chat.
  2. Write compose.yml with the NET_ADMIN capability, the tun device, and your provider's environment variables (full example below).
  3. Run docker compose up -d from that folder and watch the first pull.
  4. Check the logs with docker logs gluetun --tail 50 until you see the tunnel come up and the public IP it exited through.
  5. Confirm the exit IP is your VPN server's address, not your home IP, using the control server or a proxied curl (shown below).
  6. Attach your first app — a qBittorrent service with network_mode: service:gluetun — so its traffic rides the tunnel from the start.
services:
  gluetun:
    image: qmcgaw/gluetun:v3
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - 8888:8888/tcp   # HTTP proxy (optional)
      - 8388:8388/tcp   # Shadowsocks (optional)
      - 8388:8388/udp
      - 8080:8080       # qBittorrent web UI is published HERE, not on the qbittorrent service
    volumes:
      - ./gluetun-data:/gluetun
    env_file:
      - .env
    restart: unless-stopped
# .env — keep this file private, never commit it
VPN_SERVICE_PROVIDER=nordvpn
VPN_TYPE=openvpn
OPENVPN_USER=your_service_username
OPENVPN_PASSWORD=your_service_password
UPDATER_PERIOD=24h
TZ=America/New_York

The two lines beginners trip on are cap_add: [NET_ADMIN] and devices: [/dev/net/tun:/dev/net/tun]. NET_ADMIN lets Gluetun rewrite the container's routing tables — without it the tunnel interface can never become the default route. The /dev/net/tun device is the kernel interface OpenVPN and WireGuard write encrypted packets through. Miss either one and the container starts, logs look almost normal, and no traffic ever flows. Pin the image to :v3 rather than :latest: :v3 tracks the newest stable v3 release (v3.41.3 was current in October 2026), while :latest follows the development edge and can surprise you.

Why Do the Ports Go on the Gluetun Service?

Because network_mode: service:gluetun makes the attached container share Gluetun's entire network stack — its IP address, its routing table, its firewall. The gluetun network_mode pattern means a container attached this way has no independent network identity at all, so Docker refuses any ports: block on it and errors out with a conflicting-options message if you try. Every port any attached app needs — qBittorrent's web UI on 8080, its BitTorrent listening port, anything else — gets declared once on the gluetun service, and it all lands inside the tunnel.

This shared-stack design has two consequences worth internalizing early. First, attached containers reach each other through localhost, not through Docker service names, because from the network's point of view they are the same machine. Second, two attached containers cannot listen on the same port — there is only one stack, so one port can only be claimed once. The pattern feels strange for an hour and then becomes second nature: Gluetun owns the network, everyone else is a guest inside it.

How Do You Attach qBittorrent to Gluetun?

You add a qbittorrent service with network_mode: service:gluetun, no ports of its own, and let Gluetun publish the web UI port. This is the canonical gluetun qbittorrent pairing: the torrent client can only ever reach the internet through the VPN, and if the tunnel drops, its traffic stops dead instead of leaking onto your home connection.

services:
  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    network_mode: service:gluetun
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - WEBUI_PORT=8080
    volumes:
      - ./qbittorrent-config:/config
      - ./downloads:/downloads
    depends_on:
      - gluetun
    restart: unless-stopped

Notice what is missing: no ports: anywhere. The web UI on port 8080 was already published on the Gluetun service, and because both containers share one network stack, opening http://your-server:8080 reaches qBittorrent. The depends_on entry starts qBittorrent after Gluetun, but containers still race on a fast boot — that is exactly why the killswitch test in the next section matters more than startup ordering. If this is your first torrent client in Docker, read the qBittorrent beginner guide linked in the introduction; here Gluetun is doing the networking. And if your protected app is part of a media stack rather than a downloader, the same attach pattern covers the whole *arr family — the Plex beginner guide is the natural next stop for the server side of that stack.

How Do You Verify the Killswitch Actually Works?

You prove the gluetun killswitch by stopping Gluetun and watching the client fail. A killswitch you have never tested is a hope, not a feature — and this is the step most tutorials skip. The test takes sixty seconds and tells you the truth about your setup.

  1. With the VPN up, confirm the client's exit IP. Run docker exec qbittorrent wget -qO- https://api.ipify.org (or curl) and note the address — it should be your VPN server's IP, not your home IP.
  2. Stop Gluetun with docker stop gluetun. The tunnel interface vanishes and the firewall rules snap shut.
  3. Try the same request again from the qBittorrent container. If the killswitch works, the request hangs and then times out — no answer ever comes back, and critically, it never goes out over your home connection either.
  4. Check what your ISP would see. If that second request returns your real home IP, the killswitch is broken and your traffic is leaking. Fix it before downloading anything.
  5. Start Gluetun again with docker start gluetun, wait for the tunnel to come back, and confirm the VPN exit IP returns.

One subtlety that confuses beginners: there is no killswitch toggle to flip anywhere in Gluetun's settings. The firewall is always enforced — Gluetun installs iptables rules that block everything except the tunnel, the VPN server endpoint, your local networks, and the service ports you published. As one October 2026 guide put it, there is no separate killswitch toggle in the standard setup; the always-on firewall is the killswitch. That is why the test above matters more than any setting: it verifies behavior, not configuration.

How Does Gluetun's Firewall Handle Your Local Network?

It lets local traffic through automatically while still blocking the public internet. Gluetun's firewall rules exempt the private subnets your home network lives on, which is why you can open qBittorrent's web UI from your laptop at http://server:8080 even while every outbound packet is forced into the tunnel.

If your LAN uses something unusual, or you run services on a separate VLAN, the FIREWALL_OUTBOUND_SUBNETS variable lets you declare exactly which subnets stay reachable. You can also pin which inbound ports the firewall admits with FIREWALL_VPN_INPUT_PORTS and FIREWALL_INPUT_PORTS, and raise FIREWALL_IPTABLES_LOG_LEVEL when you need to see what the firewall is dropping. For a standard home setup you will never touch these — but knowing they exist saves you the afternoon of debugging when a weird subnet meets a strict firewall.

Which VPN Provider Works Best With Gluetun?

The best provider for Gluetun is the one whose protocol and features match what you need — there is no universal winner. Gluetun supports more than twenty providers over OpenVPN, and a smaller set natively over WireGuard. Here is the decision table beginners actually need, built from Gluetun's own provider list and its port-forwarding notes.

ProviderOpenVPNNative WireGuardPort forwarding in Gluetun
MullvadNoYes — WireGuard onlyRemoved — no longer offered
NordVPNYesYesNo
Private Internet AccessYesVia custom providerYes — for p2p apps only
ProtonVPNYesYesYes — needs WireGuard plus a Plus plan
PrivateVPNYesVia custom providerYes
Surfshark / AirVPN / IVPNYesYesNo

The two rows that surprise people are Mullvad and port forwarding. Gluetun supports gluetun mullvad over WireGuard only — pick VPN_TYPE=wireguard with Mullvad and do not bother with OpenVPN credentials. And Mullvad removed its port-forwarding feature entirely, so if forwarded ports matter to you (they improve torrent connectability), Mullvad is the wrong pick regardless of its privacy reputation. For gluetun nordvpn, both protocols work fine; use OpenVPN when you want the simplest credential setup and WireGuard when you want the fastest tunnel.

OpenVPN or WireGuard: Which Should You Pick in Gluetun?

Pick WireGuard unless you have a concrete reason not to. WireGuard connects in a fraction of a second, uses modern cryptography with a tiny codebase, and pushes more throughput on weak hardware like a Raspberry Pi or an old NAS. For a gluetun wireguard setup you supply the WireGuard key or configuration your provider generates, set VPN_TYPE=wireguard, and Gluetun handles the rest.

OpenVPN is the conservative choice: every provider Gluetun supports offers it, the credential model (username and password) is familiar, and troubleshooting is well documented because OpenVPN has been around for two decades. If your provider only issues OpenVPN credentials, or their WireGuard onboarding confuses you, gluetun openvpn with OPENVPN_USER and OPENVPN_PASSWORD is a perfectly good tunnel. The killswitch protects both protocols identically — the firewall does not care how the tunnel was built.

How Do You Turn On Port Forwarding?

You set VPN_PORT_FORWARDING=on and let Gluetun negotiate a forwarded port from your provider, then point your torrent client's listening port at it. Gluetun port forwarding lets incoming peers connect to you directly instead of only through outbound connections, which noticeably improves speeds and swarm health for a client behind a VPN.

Gluetun supports port forwarding natively for Private Internet Access, PrivateVPN, and ProtonVPN — and the details differ per provider. PIA's forwarding works only for peer-to-peer applications, per the maintainer's own warning. ProtonVPN requires WireGuard and a Plus-tier plan; it will not work over OpenVPN or on the free tier. Gluetun writes the assigned port to /tmp/gluetun/forwarded_port, and with the ./gluetun-data:/gluetun volume mounted, a PIA forwarded port persists for up to 60 days across restarts. If your client needs to react when the port changes, VPN_PORT_FORWARDING_UP_COMMAND and VPN_PORT_FORWARDING_DOWN_COMMAND run your scripts on port assignment and removal — the standard trick is a small script that updates qBittorrent's listening port through its API.

How Do You Keep Gluetun Updated?

You pull the image and recreate the container, and you let Gluetun refresh its own server list on a schedule. VPN providers add and retire servers constantly, so Gluetun ships a built-in updater: UPDATER_PERIOD=24h tells it to fetch fresh server and configuration data once a day. Set it once and forget it.

For the container itself, run docker compose pull gluetun && docker compose up -d gluetun whenever you want the newest release — attached containers keep working because their network stack is just borrowed from Gluetun. Pinning image: qmcgaw/gluetun:v3 keeps you on the stable v3 line instead of the development edge. One forward-looking note: Gluetun's docs mark the forwarded-port status file as deprecated in the upcoming v4.0.0, which had not been released as of October 2026 — when v4 lands, read its migration notes before upgrading.

How Do You Check Gluetun's Health and Control Server?

Gluetun watches itself so you do not have to. Every minute it pings its ICMP targets (defaulting to Cloudflare and Google DNS), falling back to plaintext DNS if ICMP is blocked, and every five minutes it performs a full TCP-plus-TLS dial to its target addresses, defaulting to cloudflare.com and github.com on port 443. If either check fails, Gluetun restarts the VPN connection inside the container on its own — you will see it in the logs as a reconnection, not an outage.

For your own checks, Gluetun runs a REST control server on port 8000 by default, with a separate health endpoint server on 127.0.0.1:9999. Publish port 8000 on the Gluetun service the same way you published 8080, and you can query tunnel status, the public IP, and port-forwarding state programmatically. If you want that status behind a proper domain with HTTPS, the Caddy beginner guide shows how to reverse-proxy a container port cleanly.

What Are the Beginner Mistakes That Break Gluetun?

Almost every Gluetun failure report traces back to one of seven mistakes, and all seven are configuration, not software bugs. Run through this table before you post a help request — the fix is usually one line.

MistakeWhat happensThe fix
Missing NET_ADMINContainer starts but the tunnel never comes upAdd cap_add: [NET_ADMIN] to the gluetun service
Missing /dev/net/tunOpenVPN/WireGuard cannot create the tunnel interfaceAdd the devices mapping exactly as shown above
Ports on the client serviceDocker errors about conflicting optionsMove every ports: entry onto the gluetun service
Website login instead of service credentialsAuthentication rejected, tunnel loops on retryGenerate dedicated OpenVPN/WireGuard credentials in your provider dashboard
Secrets committed to gitCredentials leak to anyone with repo accessKeep them in .env, add .env to .gitignore
Assuming the killswitch worksSilent leaks if anything was misconfiguredRun the stop-and-curl test from this guide before trusting it
Port forwarding expected on MullvadNothing to forward — the feature is gonePick PIA, PrivateVPN, or ProtonVPN if you need forwarded ports

Sources

  1. Gluetun README — github.com/qdm12/gluetun (provider list, compose requirements, image tags; notes the planned migration to the passtque org), fetched 2026-11-03.
  2. Gluetun wiki, firewall options — firewall is always enforced; no on/off toggle; FIREWALL_OUTBOUND_SUBNETS and related variables, fetched 2026-11-03.
  3. ssdnodes.com Gluetun guide, October 2026 — v3.41.3 current, :v3 tag guidance, ICMP and TCP+TLS health checks, fetched 2026-11-03.
  4. dev.to, "How to actually set up the Gluetun VPN killswitch" — the verification gap: setup is covered everywhere, verifying the killswitch is not; stop-and-curl test, fetched 2026-11-03.
  5. devhandbook.io, "Route qBittorrent Through a VPN With Gluetun" — Gluetun plus qBittorrent compose arc, Mullvad port-forwarding removal, fetched 2026-11-03.
  6. cyberpanel.net, "Gluetun Docker: How to Expertly SetUp a VPN Proxy in 2026" — current-year compose walkthrough, fetched 2026-11-03.
  7. code.mendhak.com, "How to run any Docker container's traffic through Wireguard or OpenVPN" — network_mode behavior, localhost communication, fetched 2026-11-03.
  8. umatechnology.org, October 2026 — no separate killswitch toggle in the standard setup, fetched 2026-11-03.
  9. muffn.io — ProtonVPN port forwarding requires WireGuard plus a Plus plan, fetched 2026-11-03.
  10. DeepWiki, Gluetun HTTP control API and port-forwarding settings — port 8000 control server, VPN_PORT_FORWARDING variables, fetched 2026-11-03.

Frequently Asked Questions

Do I need NET_ADMIN for Gluetun?

Yes. NET_ADMIN is the Linux capability that lets Gluetun rewrite the container's routing tables and bring up the tunnel interface. Without it the container starts but no traffic ever flows through the VPN, and the logs will not always make the cause obvious. Pair it with the /dev/net/tun device mapping — both are mandatory, and both live on the gluetun service.

Does Gluetun have a killswitch toggle?

No, and that is deliberate. Gluetun's firewall is always on: iptables rules block every packet except what goes through the tunnel, the VPN endpoint, your local networks, and your published service ports. There is nothing to enable and nothing to accidentally disable. The right move is not flipping a setting but running the stop-and-curl test in this guide to prove the behavior on your machine.

Can I use Gluetun with Mullvad?

Yes, over WireGuard only — Gluetun does not support Mullvad over OpenVPN. Generate a WireGuard key in your Mullvad account, set VPN_TYPE to wireguard, and use your Mullvad account number with the key. Just remember Mullvad removed port forwarding, so if forwarded ports matter to your setup, choose a different provider.

Why does my attached container say connection refused?

Almost always because the port was declared on the wrong service. Containers using network_mode: service:gluetun have no ports of their own; every port must be published on the gluetun service. Move the ports block, recreate both containers, and the connection refused error disappears. The other common cause is Gluetun itself not being healthy yet — check docker logs gluetun first.

Does Gluetun work on a NAS like Synology or Unraid?

Yes, with one caveat. Any host that runs Docker can run Gluetun, including Synology and Unraid boxes, but the host kernel must expose /dev/net/tun and Docker must allow the NET_ADMIN capability — most NAS Docker implementations do. If your NAS runs containers in a restricted mode that blocks capabilities, Gluetun cannot build the tunnel and you will need a regular Linux host or VPS instead.

Featured on Twelve Tools Hunt for Tools Featured on LaunchBuff Launch Llama Tools Launch your MCP