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.
- Make a folder for the project, for example
~/gluetun, and inside it create an.envfile with your provider credentials. Secrets live here, never committed to git, never pasted into a chat. - Write
compose.ymlwith the NET_ADMIN capability, the tun device, and your provider's environment variables (full example below). - Run
docker compose up -dfrom that folder and watch the first pull. - Check the logs with
docker logs gluetun --tail 50until you see the tunnel come up and the public IP it exited through. - Confirm the exit IP is your VPN server's address, not your home IP, using the control server or a proxied curl (shown below).
- 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.
- 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. - Stop Gluetun with
docker stop gluetun. The tunnel interface vanishes and the firewall rules snap shut. - 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.
- 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.
- 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.
| Provider | OpenVPN | Native WireGuard | Port forwarding in Gluetun |
|---|---|---|---|
| Mullvad | No | Yes — WireGuard only | Removed — no longer offered |
| NordVPN | Yes | Yes | No |
| Private Internet Access | Yes | Via custom provider | Yes — for p2p apps only |
| ProtonVPN | Yes | Yes | Yes — needs WireGuard plus a Plus plan |
| PrivateVPN | Yes | Via custom provider | Yes |
| Surfshark / AirVPN / IVPN | Yes | Yes | No |
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.
| Mistake | What happens | The fix |
|---|---|---|
Missing NET_ADMIN | Container starts but the tunnel never comes up | Add cap_add: [NET_ADMIN] to the gluetun service |
Missing /dev/net/tun | OpenVPN/WireGuard cannot create the tunnel interface | Add the devices mapping exactly as shown above |
| Ports on the client service | Docker errors about conflicting options | Move every ports: entry onto the gluetun service |
| Website login instead of service credentials | Authentication rejected, tunnel loops on retry | Generate dedicated OpenVPN/WireGuard credentials in your provider dashboard |
| Secrets committed to git | Credentials leak to anyone with repo access | Keep them in .env, add .env to .gitignore |
| Assuming the killswitch works | Silent leaks if anything was misconfigured | Run the stop-and-curl test from this guide before trusting it |
| Port forwarding expected on Mullvad | Nothing to forward — the feature is gone | Pick PIA, PrivateVPN, or ProtonVPN if you need forwarded ports |
Sources
- Gluetun README — github.com/qdm12/gluetun (provider list, compose requirements, image tags; notes the planned migration to the passtque org), fetched 2026-11-03.
- Gluetun wiki, firewall options — firewall is always enforced; no on/off toggle; FIREWALL_OUTBOUND_SUBNETS and related variables, fetched 2026-11-03.
- ssdnodes.com Gluetun guide, October 2026 — v3.41.3 current, :v3 tag guidance, ICMP and TCP+TLS health checks, fetched 2026-11-03.
- 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.
- devhandbook.io, "Route qBittorrent Through a VPN With Gluetun" — Gluetun plus qBittorrent compose arc, Mullvad port-forwarding removal, fetched 2026-11-03.
- cyberpanel.net, "Gluetun Docker: How to Expertly SetUp a VPN Proxy in 2026" — current-year compose walkthrough, fetched 2026-11-03.
- code.mendhak.com, "How to run any Docker container's traffic through Wireguard or OpenVPN" — network_mode behavior, localhost communication, fetched 2026-11-03.
- umatechnology.org, October 2026 — no separate killswitch toggle in the standard setup, fetched 2026-11-03.
- muffn.io — ProtonVPN port forwarding requires WireGuard plus a Plus plan, fetched 2026-11-03.
- 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.
