Routes Tailscale exit-node traffic through a commercial VPN provider using Gluetun + the official Tailscale image.
When a Tailscale client selects this node as an exit node, all its internet traffic leaves through the VPN tunnel.
Tailscale client
│ (encrypted Tailscale tunnel)
▼
┌─────────────────────────────────────────┐
│ Docker host │
│ │
│ ┌──────────────────────────────────┐ │
│ │ gluetun (qmcgaw/gluetun) │ │
│ │ owns /dev/net/tun + VPN route │ │
│ │ │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ tailscale │ │ │
│ │ │ (tailscale/tailscale) │ │ │
│ │ │ network_mode: gluetun │ │ │
│ │ │ TS_USERSPACE=true │ │ │
│ │ └──────────────────────────┘ │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────┘
│ (VPN-encrypted traffic)
▼
VPN provider → Internet
tailscale shares the network namespace of gluetun via
network_mode: "service:gluetun". Every packet Tailscale forwards exits
through the WireGuard/OpenVPN tunnel that Gluetun maintains.
TS_USERSPACE=true is required because Gluetun already owns /dev/net/tun;
Tailscale uses its built-in userspace network stack instead of opening a second
tun device.
- A Gluetun-supported VPN provider (Mullvad, AirVPN, NordVPN, ProtonVPN, Surfshark, …). Full list and per-provider variables: https://github.com/qdm12/gluetun-wiki
- A Tailscale auth key (Reusable + Pre-authorized recommended).
Edit docker-compose.yaml and replace the Gluetun environment variables with
your provider's credentials. The default example uses Mullvad WireGuard:
environment:
- VPN_SERVICE_PROVIDER=mullvad
- VPN_TYPE=wireguard
- WIREGUARD_PRIVATE_KEY=<your-private-key>
- WIREGUARD_ADDRESSES=10.64.0.1/32
# - SERVER_COUNTRIES=Netherlandsenvironment:
- TS_AUTHKEY=tskey-auth-xxxxxxxxdocker compose up -dIn the Tailscale admin console (https://login.tailscale.com/admin/machines) find the new node and enable "Use as exit node".
| Variable | Default | Description |
|---|---|---|
TS_AUTHKEY |
(required) | Tailscale auth key |
TS_EXTRA_ARGS |
--advertise-exit-node --advertise-connector --accept-dns=false |
Extra tailscale up flags |
TS_STATE_DIR |
/var/lib/tailscale |
State directory |
TS_USERSPACE |
true |
Must stay true when sharing Gluetun's namespace |
Provider-specific — see the Gluetun wiki.
This project is licensed under the MIT License - see the LICENSE file for details.