Files
docker-compose-repo/gluetun/compose.yaml
T
Goyban 18e468c88f added gluetun with qBittorrent and pyload-ng
VPN kill switch via shared network namespace, TorGuard WireGuard through
gluetun's custom provider. compose.yaml is the maintained version;
compose.personal.yaml is the variant actually running, kept as-is.

Verified against gluetun's own settings summary: SOCKSPROXY/SOCKSPROXY_PORT
are not real variables and the SOCKS5 server never starts; HTTPPROXY_PORT is
deprecated; pyload-ng listens on 8000, not 8880.

.gitignore: ignore wg*.conf and *.ovpn everywhere, because add gluetun/compose.yaml gluetun/compose.personal.yaml gluetun/.env.example gluetun/README.md .gitignore/init/** would
otherwise commit a WireGuard private key dropped in a service's init/ dir.
Un-ignore compose.personal.yaml narrowly, so compose.override.yaml stays out.
2026-09-07 10:41:40 +02:00

96 lines
3.5 KiB
YAML

# The maintained version of this stack -- this is what `docker compose up`
# uses. See compose.personal.yaml for the older variant still running on
# my own box, and the README for what differs between them.
services:
gluetun:
# Pinned. This container holds the tunnel; an unattended pull breaking it
# means the download clients lose all connectivity (by design).
image: qmcgaw/gluetun:v3.41.3
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
environment:
- VPN_SERVICE_PROVIDER=custom
- VPN_TYPE=wireguard
# SOCKS5 proxy. The names matter: SOCKSPROXY / SOCKSPROXY_PORT are NOT
# gluetun variables -- it ignores them silently and the proxy never
# starts. Verified against gluetun's own settings summary.
- SOCKS5_ENABLED=on
- SOCKS5_LISTENING_ADDRESS=:1080
# HTTP proxy. HTTPPROXY_PORT still works but logs a deprecation warning;
# LISTENING_ADDRESS is the current name.
- HTTPPROXY=on
- HTTPPROXY_LISTENING_ADDRESS=:8888
# Proxy authentication. Empty means NO authentication -- anyone who can
# reach the published ports can use the VPN. Set both vars in .env to
# turn it on; leaving them unset keeps the current behaviour.
- HTTPPROXY_USER=${PROXY_USER:-}
- HTTPPROXY_PASSWORD=${PROXY_PASSWORD:-}
- SOCKS5_USER=${PROXY_USER:-}
- SOCKS5_PASSWORD=${PROXY_PASSWORD:-}
ports:
- "${QBT_PORT:-9880}:9880/tcp" # qBittorrent Web UI
# pyload-ng listens on 8000 inside the container and the port is not
# settable by environment variable -- only in pyload's own config.
- "${PYLOAD_PORT:-8880}:8000/tcp" # pyLoad Web UI
- "${SOCKS_PORT:-9980}:1080/tcp" # SOCKS5 proxy
- "${HTTPPROXY_PORT:-9998}:8888/tcp" # HTTP proxy
# Incoming BitTorrent peers. Needs a forwarded port from TorGuard, and
# the number here must match TORRENTING_PORT below.
#- "6881:6881/tcp"
#- "6881:6881/udp"
volumes:
- /etc/localtime:/etc/localtime:ro
# Bind mount of a FILE. It must exist before the first `up` or Docker
# creates a directory here and gluetun finds no config. Git-ignored.
- ./wg0.conf:/gluetun/wireguard/wg0.conf:ro
restart: unless-stopped
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-Etc/UTC}
- WEBUI_PORT=9880
- TORRENTING_PORT=6881
volumes:
- ${CONFIG_PATH:-./config}:/config
- "${TEMPDISK:?set TEMPDISK in .env to the disk your downloads live on}/downloads/torrents:/downloads"
# No network of its own: everything goes through the tunnel, and there is
# no route out if the tunnel drops. This is also why it cannot declare
# its own `ports:` -- they live on gluetun above.
network_mode: "service:gluetun"
depends_on:
gluetun:
# gluetun ships a healthcheck; wait for the tunnel rather than racing it.
condition: service_healthy
restart: unless-stopped
pyload-ng:
image: lscr.io/linuxserver/pyload-ng:latest
container_name: pyload-ng
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-Etc/UTC}
volumes:
- ${PYLOAD_CONFIG_PATH:-./pyloadconfig}:/config
- ${TEMPDISK}/downloads/pyload:/downloads
network_mode: "service:gluetun"
depends_on:
gluetun:
condition: service_healthy
restart: unless-stopped