Gluetun: a VPN client container that routes other containers through it
VPN client in a thin Docker container for multiple VPN providers, written in Go, and using OpenVPN or Wireguard, DNS over TLS, with a few proxy servers built-in.
At a glance
- What is it?
- Gluetun is a Go VPN client packaged as a small Docker image. It supports OpenVPN and WireGuard across a long list of providers, plus DNS over TLS and built-in proxy servers, so other containers and LAN devices can share one tunnel.
- Who is it for?
- Gluetun fits anyone already running Docker or Compose who wants one tunnel shared by several services, and it is a poor fit for someone who wants a desktop VPN toggle or a provider it does not list. Before adopting it, read the provider page in the gluetun-wiki for your provider, confirm whether it needs OpenVPN or WireGuard, and check that your host can pass /dev/net/tun and grant NET_ADMIN, because without those two the container cannot build a tunnel at all.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Gluetun is for, and who ends up using it
Gluetun is a VPN client that runs as a container rather than as software on your desktop. The README describes it as a "Lightweight swiss-army-knife-like VPN client to multiple VPN service providers", written in Go and built on Alpine 3.23, which the README puts at a 43.1MB image.
The problem it addresses is not "I want a VPN on my laptop". It is "I have a download client, a media server or a scraper in Docker, and I want its traffic to leave through a VPN without configuring a VPN client inside each of those containers". Gluetun connects once, then other containers point their network at it, and the README links a wiki page titled Connect other containers to it for that workflow. LAN devices can be routed through it too, via a separate wiki page.
The audience is therefore people who already manage containers and are comfortable with ports, capabilities and device mounts. If you have never edited a Compose file, the provider-specific wiki pages are the intended entry point; the repository itself does not walk a beginner through the concepts.
How the tunnel, DNS and proxies fit together
The container holds the VPN connection and exposes it to whatever else you attach. Three mechanisms do the work.
First, the tunnel itself. Gluetun supports OpenVPN for every provider it lists, and WireGuard for a subset: the README names AirVPN, FastestVPN, Ivpn, Mullvad, NordVPN, ProtonVPN, Surfshark and Windscribe as native WireGuard providers, with Cyberghost, Private Internet Access, PrivateVPN, PureVPN, Torguard, VPN Unlimited and VyprVPN reachable through a custom provider configuration. Mullvad is listed as WireGuard only. WireGuard runs both in kernel space and in user space, which matters on hosts where the kernel module is unavailable.
Second, name resolution. DNS over TLS is built in, with the provider of your choice, and Gluetun can block malicious and advertising hostnames and IP addresses with a live update every 24 hours. It can also do split horizon DNS by selecting multiple DNS over TLS providers, so different names resolve through different upstreams.
Third, the proxies. HTTP, SOCKS5 and Shadowsocks servers are built in, and the README notes that the Shadowsocks and SOCKS5 servers tunnel both TCP and UDP while the HTTP proxy carries HTTP and HTTPS over TCP. That UDP support is the reason a torrent client can sit behind the SOCKS5 or Shadowsocks proxy rather than sharing the whole network namespace. A firewall kill switch restricts traffic to the VPN servers and LAN devices you allow.
One design consequence is worth stating plainly: because everything shares one tunnel, a provider outage or a credential change takes down every container attached to Gluetun at once. There is no per-service tunnel to fall back on.
Installing Gluetun and getting a first container through it
The image is published as qmcgaw/gluetun on Docker Hub and also as ghcr.io/qdm12/gluetun. The README points at the gluetun-wiki for setup, and provides a Compose file for what it calls the laziest case. The essential parts are the NET_ADMIN capability and the /dev/net/tun device; without them the tunnel cannot be created. The ports below map the HTTP proxy on 8888 and Shadowsocks on 8388 for both TCP and UDP.
---
services:
gluetun:
image: qmcgaw/gluetun
# container_name: gluetun
# line above must be uncommented to allow external containers to connect.
# See https://github.com/qdm12/gluetun-wiki/blob/main/setup/connect-a-container-to-gluetun.md#external-container-to-gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
- 8888:8888/tcp # HTTP proxy
- 8388:8388/tcp # Shadowsocks
- 8388:8388/udp # Shadowsocks
volumes:
- /yourpath:/gluetun
environment:
# See https://github.com/qdm12/gluetun-wiki/treThe README's Compose snippet is truncated at the environment block, and it does not list the variable names in the repository itself. Those live on the provider pages in the wiki, which is where you should look up the exact keys for your provider rather than guessing. The README also notes that the container_name line must be uncommented before external containers can connect, which is the detail people miss first.
Once the stack is up, the wiki page linked in that comment is the place to look for how a second container attaches to Gluetun's network rather than keeping its own. That is the step that turns a running VPN container into a shared tunnel for the rest of your stack.
Where Gluetun is the wrong tool
Provider coverage is the first boundary. The README lists a specific set of supported services, and if yours is not on it you are pushed into the custom provider path, which means supplying your own OpenVPN or WireGuard configuration. That is workable for WireGuard and for AmneziaWG, which the README says is supported only through the custom provider for now, but it is not the same as first-class support: you own the config, the endpoint choice and any breakage when the provider changes something.
WireGuard support is uneven in a way that is easy to misread. Mullvad is WireGuard only, and several providers appear in the OpenVPN list but reach WireGuard only through the custom provider. If you pick a provider for its WireGuard performance and it is in the second group, you are maintaining a config file rather than using a built-in integration.
The architecture is also a single point of failure by design. One container holds one tunnel. If it restarts, everything attached to it loses networking for the duration. Running two Gluetun containers for redundancy means two sets of credentials and two sets of attached services, and the README does not describe a failover mode.
Finally, the repository is not a user interface. There is no dashboard in the README's feature list. Configuration is environment variables and files under /gluetun, and troubleshooting happens by reading container logs against the wiki's common errors page. Someone who wants a click-to-connect client on a laptop should not adopt this.
Compared with running the VPN client inside each container
The obvious alternative is not another project but a different arrangement: install the VPN client in the same container as the application, or run the provider's own client on the host and route traffic at the host level.
The difference is where the connection state lives. With Gluetun, one process owns authentication, key exchange, DNS and the firewall, and the applications are unaware of any of it. With a per-container client, each application image needs the VPN binaries added, needs its own credentials, and reconnects on its own schedule. That is more moving parts, but it also means one failing tunnel does not take the others down, and a provider change affects one service rather than all of them.
Host-level routing sits between the two. It avoids the NET_ADMIN and /dev/net/tun requirements in the application containers, but then every process on the host is subject to the same routing rules unless you write policy routing yourself, which is exactly the work Gluetun's firewall and proxy servers exist to avoid.
The built-in proxies are the part with no direct equivalent in the per-container approach. Exposing an HTTP or SOCKS5 endpoint on 8888 or 8388 lets a single application opt into the tunnel without giving up its own network namespace, which is useful when only one service should be tunnelled.
Maintenance, releases and the licence
The repository is not archived, and the most recent push recorded is 2026-07-30, which is the same date as release v3.41.3. The two releases before it were v3.41.2 on 2026-07-29 and v3.41.1 on 2026-02-11. That pattern, a pair of releases a day apart followed by a gap of several months, suggests maintenance driven by fixes rather than a fixed cadence.
Upgrade cost is mostly the image tag. Because configuration lives in environment variables and a volume at /gluetun, replacing the image does not rewrite your settings, but provider-side changes can break a working setup without a Gluetun release: the supported provider list and the WireGuard coverage are maintained by the project, and the README points to an open issue for providers still in progress. Pin the image tag if you do not want a pull to change behaviour underneath a running stack.
The README states the project is migrating to github.com/passteque/gluetun, and explicitly says the Docker image names will remain the same. That matters for anyone pinning by image reference or watching a repository URL: the image path is the stable part.
Licensing is MIT, per the LICENSE file at the repository root. That is permissive and places few conditions on redistribution, but the licence covers Gluetun's own code. Your VPN provider's terms of service are a separate matter, and nothing in the repository governs how many simultaneous connections your account permits. This is not legal advice; read the LICENSE file and your provider's terms yourself.
Editorial conclusion
Gluetun fits anyone already running Docker or Compose who wants one tunnel shared by several services, and it is a poor fit for someone who wants a desktop VPN toggle or a provider it does not list. Before adopting it, read the provider page in the gluetun-wiki for your provider, confirm whether it needs OpenVPN or WireGuard, and check that your host can pass /dev/net/tun and grant NET_ADMIN, because without those two the container cannot build a tunnel at all.
Frequently asked questions
What is Gluetun used for?
It runs a VPN connection inside a Docker container and lets other containers and LAN devices send their traffic through that tunnel. The README also lists built-in HTTP, SOCKS5 and Shadowsocks proxy servers, DNS over TLS, and a firewall kill switch.
How do I set up Gluetun?
The README directs setup to the gluetun-wiki, which has provider-specific pages. The repository's own Compose example uses the qmcgaw/gluetun image with the NET_ADMIN capability and the /dev/net/tun device, and maps ports 8888 and 8388.
Can I use Gluetun VPN with NordVPN?
NordVPN appears in the README's list of supported providers, and it is one of the providers listed as supporting WireGuard natively. The README points to the wiki for the provider-specific configuration steps.
How do I install Gluetun with Docker?
Pull the image qmcgaw/gluetun, or ghcr.io/qdm12/gluetun, and start it with the NET_ADMIN capability plus /dev/net/tun mapped into the container. The README's Compose example also mounts a host path at /gluetun for persistent configuration.
What VPN works best with Gluetun?
The README does not rank providers. It lists which ones support OpenVPN and which also support WireGuard natively, so the practical choice is whether your provider is in the native WireGuard group or needs the custom provider path.
How do I use Gluetun?
Start the container with the NET_ADMIN capability and /dev/net/tun, then either attach other containers to its network namespace or send traffic to its built-in HTTP proxy on 8888 or its Shadowsocks and SOCKS5 endpoints on 8388.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/passteque-gluetun)