-
-
Notifications
You must be signed in to change notification settings - Fork 2
Features
-
Sidecar mode (default) — a
gluetun-companion-testcontainer clones the real Gluetun config for each server;gluetun-companion-sidecarmeasures speed via Ookla + librespeed in parallel (dual mode, default), Ookla only, librespeed only, or iperf3 directly inside the VPN tunnel; your main Gluetun is never restarted during testing - HTTP proxy mode (optional) — measures speed via the Gluetun HTTP proxy with no extra containers; briefly interrupts dependent services on each server switch
- Multi-source results — Ookla, librespeed and iperf3 speeds stored separately and displayed in the dashboard and history
- Multi-stream download — N concurrent TCP connections (configurable, default: 4)
- Automatic benchmarking every X hours — download, upload and latency per server; automatic cycle can be disabled (manual trigger only)
- Smart benchmark selection (option) — avoids huge cycles on massive catalogues: tests the best known servers for the usage profile, explores a few new servers and refreshes old measurements
-
Allowed servers before benchmark (option) — select which entry types to include in each cycle (
SERVER_NAMES,SERVER_COUNTRIES,SERVER_CITIES,SERVER_REGIONS,SERVER_HOSTNAMES) and, for AirVPN, skip overloaded servers; excluded servers remain in the list and can be tested manually - Quick check before benchmark (option) — tests only the current server before each cycle; if speed is within ±N% of the last known result, the full benchmark is skipped entirely — no containers paused, no VPN restarts; triggers the full benchmark only when performance drifts significantly
- Time optimization (option) — analyses hourly speed and variance patterns to identify the best and worst benchmark windows; recommended time slots displayed in Settings; optional auto-shift: if the next cycle falls on an unfavorable hour, it is shifted up to 3 h forward to the next favorable window
- On-demand quick benchmark — button always available (dashboard and settings); tests only the active server via the Gluetun HTTP proxy, result in seconds, no VPN interruption, result saved in history
-
Duration estimate — the dashboard shows a dynamically calculated duration range (optimistic / pessimistic) based on your settings (
wait_secs,duration,samples,retries, sidecar or proxy mode); automatic⚠️ alert if the estimated total exceeds 30 minutes; the same estimate is shown live in Settings as you adjust parameters - Jitter & Packet Loss — network stability measured at every test (21 TTFB probes in proxy mode, TCP handshakes via sidecar); 🟢/🟡/🔴 indicator on Servers page, dedicated columns in History, jitter shown in hourly patterns; factored into selection score (up to −15 % jitter / −25 % loss penalty)
-
DNS latency (sidecar) — DNS resolution time measured from inside the VPN tunnel via
dig(4 domains in parallel, median returned); detects slow, overloaded, or hijacking resolvers; column in History, DNS shown in the Stability tooltip, data in hourly patterns -
Docker events listener — daemon thread watching for Gluetun container
startevents; if Gluetun restarts on its own (crash, update, watchdog), automatically triggers a quick check after N seconds (VPN reconnect delay); if speed drift exceeds the configured threshold and auto-switch is enabled, immediately runs a full benchmark; restarts triggered by Companion itself are ignored; 5-minute cooldown between triggers
Companion separates two pieces of information:
- the DNS intermediary read from the Gluetun configuration, for example
Local DNS (192.168.0.64); - the resolvers actually observed on the Internet, for example
Cloudflare, Quad9.
When a private tunnel address appears to belong to the VPN provider, the UI remains cautious: Probable intermediary: AirVPN VPN provider DNS (10.x.x.x). No local software such as AdGuard Home or Pi-hole is assumed or required.
Universal detection uses the free bash.ws service: a temporary sidecar sharing Gluetun's network requests an identifier, triggers ten unique resolutions, then retrieves the observed resolver IPs, ASNs and countries. No docker exec or additional Docker socket access is required. Results are cached for six hours to limit requests. This operation discloses the VPN IP and test DNS queries to the third-party service, but no Companion identifier or user-browsed domain.
The VPN Status card displays the intermediary and observed operators. In tables, only DNS latency remains visible; details are provided in a tooltip. The state is also exposed by GET /api/v1/status under dns_path (intermediary, resolvers, observed_summary, tested_at).
-
Automatic switching to the fastest server (
docker compose up -d), based on a weighted score combining current speed, exponential history, jitter, packet loss and involuntary reconnects (via Docker events); configurable Speed vs stability slider; 6 usage profiles (Balanced, Gaming, BitTorrent, DDL, Download, Streaming) — each profile weights metrics differently to find the server best suited to your actual use case; dependent services (network_mode: service:gluetun) are recreated automatically - Independent emergency failover — a watchdog checks Gluetun health every 30 seconds and selects the best historical server from the same profile after a configurable grace period, even when performance-based automatic switching is disabled; includes an anti-flapping cooldown, dependent recreation and a critical notification
- Global country exclusions — select countries from Servers → Excluded countries (or Settings) to remove them from AirVPN/catalogue pickers, benchmarks, emergency failover and automatic pool rotations without removing existing servers; manual tests and switches remain available
-
Manual switch to any configured server from the Servers page — Gluetun is reconfigured and
network_mode: service:gluetuncontainers are recreated automatically -
5 filter types:
SERVER_NAMES,SERVER_COUNTRIES,SERVER_REGIONS,SERVER_CITIES,SERVER_HOSTNAMES - Configurable retry per server + global timeout per server
- Auto-disable a server after N consecutive failures
- Rotation without benchmarking — switch to a server from a predefined group without triggering a full measurement cycle; ideal for periodic rotation or quick one-off changes
-
Readable candidate rules — each pool starts from simple rules: specific server, Gluetun filter type (
SERVER_NAMES,SERVER_COUNTRIES,SERVER_CITIES,SERVER_REGIONS,SERVER_HOSTNAMES), VPN profile, top metric, or all active servers. Rules can either add their results or keep only servers matching every rule. - Per-pool exclusions — exclude specific servers from one pool without disabling them in Companion; they remain available elsewhere, but this pool will never pick them.
- 3 selection modes: 🎲 random, 🔄 round-robin (persistent cursor across rotations), 🏆 best historical download
- Final limit — after rules and exclusions, restrict the pool to the N best historical download speeds (if unset, all remaining candidates are eligible)
- Manual or scheduled — instant one-click rotation from the UI, or automatic rotation on a configurable interval (in hours; e.g. every 12 h or every 2 days)
-
Optional post-switch measurement — after each switch, a fast proxy test measures the new server's speed and records it in the history (method
proxy_qc). This measurement does not choose the server; it audits the completed rotation. - Notifications — Discord/Apprise alert on each rotation (manual or automatic), including previous server, new server, and speed if post-switch measurement is enabled
- VPN profiles — create multiple sets of credentials from Settings → VPN profiles; each profile is linked to a provider and a connection type (WireGuard or OpenVPN, depending on what Gluetun supports natively for that provider); all 24 providers from the Gluetun wiki are integrated
-
Secret encryption — private keys, OpenVPN passwords and other sensitive fields are encrypted at rest (Fernet/AES-128, key derived from
SECRET_KEYvia PBKDF2HMAC-SHA256 with 480 000 iterations); changingSECRET_KEYmakes existing profiles unreadable (documented behavior) -
Server ↔ profile assignment — on the Servers page, assign a VPN profile to each server via a dropdown; a Provider column shows the linked profile; the
?profile=filter limits the view to a single profile or to unassigned servers - Orphan server alert — a badge warns when servers have no assigned profile while at least one VPN profile is configured; those servers continue to work normally but cannot be selected by the multi-profile benchmark
-
Multi-profile benchmark — in sidecar mode, each server is tested with its profile's credentials injected into the temporary container; on the final switch, Companion automatically writes
VPN_SERVICE_PROVIDER,VPN_TYPEand all credential variables (WIREGUARD_*orOPENVPN_*) todocker-compose.override.yml, blanking credentials inherited from the base compose file so nothing leaks between providers - Sidecar and OpenVPN — OpenVPN profiles are tested with the same credentials as the main tunnel (most providers allow several simultaneous connections); the dedicated sidecar key only applies to WireGuard profiles
-
Rotation policy — three modes configurable in Settings → VPN profiles → Rotation policy:
-
none— Companion always stays in the currently active profile; servers from other profiles are never selected -
free— picks the best server across all profiles (default behavior without profiles) -
conditional— switches to another profile only if its best server outperforms the best server in the current profile by more than N % (configurable threshold, default 10 %)
-
-
Provider column in
/history— each history row shows the VPN profile associated with the tested server (only visible when at least one profile is configured)
Integrated providers (from the Gluetun wiki):
| Provider | WireGuard | OpenVPN | OpenVPN credentials |
|---|---|---|---|
| AirVPN | Native | Native | Client certificate + key (OPENVPN_CERT, OPENVPN_KEY) |
| CyberGhost | Via custom
|
Native |
OPENVPN_USER/OPENVPN_PASSWORD + client certificate + key |
| ExpressVPN | — | Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| FastestVPN | Native | Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| Giganews (VyprVPN) | — | Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| HideMyAss | — | Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| IPVanish | — | Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| IVPN | Native | Native |
OPENVPN_USER (password optional with the account ID) |
| Mullvad | Native | — | OpenVPN removed by Mullvad in January 2026 |
| NordVPN | Native | Native | Service credentials (OPENVPN_USER/OPENVPN_PASSWORD) |
| Perfect Privacy | — | Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| Privado | — | Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| Private Internet Access | Via custom
|
Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| PrivateVPN | Via custom
|
Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| ProtonVPN | Native | Native | Dedicated OpenVPN credentials (+pmp for port forwarding) |
| PureVPN | Via custom
|
Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| SlickVPN | — | Native |
OPENVPN_USER/OPENVPN_PASSWORD + certificate + encrypted key |
| Surfshark | Native | Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| TorGuard | Via custom
|
Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| VPN Secure | — | Native | Certificate + encrypted key + passphrase (OPENVPN_KEY_PASSPHRASE) |
| VPN Unlimited | Via custom
|
Native |
OPENVPN_USER/OPENVPN_PASSWORD + client certificate + key |
| VyprVPN | Via custom
|
Native |
OPENVPN_USER/OPENVPN_PASSWORD
|
| Windscribe | Native | Native |
OPENVPN_USER/OPENVPN_PASSWORD (from a generated config file) |
| Custom | Native | Native |
.conf file mounted into Gluetun + optional credentials |
Client certificates and keys (CyberGhost, VPN Unlimited, AirVPN OpenVPN, SlickVPN, VPN Secure) go straight into the form: paste the base64 body as a single line (without the
BEGIN/ENDmarkers) — no file mount needed.Custom WireGuard remains available for any provider without native WireGuard support in Gluetun (CyberGhost, PIA, PrivateVPN, PureVPN, TorGuard, VPN Unlimited, VyprVPN…) as long as it provides a standard WireGuard configuration file.
-
Real Gluetun catalogue first — the catalogue Sidecar automatically mounts the Gluetun container's
/gluetunvolume when it is available and reads/gluetun/servers.jsonfirst; this is the exact list loaded by Gluetun. If that volume is not available, Companion falls back to the publicqdm12/gluetun-serversrepository -
Automatic refresh — the list is updated at every benchmark cycle (configurable interval in Settings → Measure, default: 6 h); a dedicated button in Settings and in the
/serversmodal lets you force an immediate refresh -
Auto-add new servers (option) — when new servers appear in the catalogue for a country, region or city you already have configured, Companion automatically adds them to your server list (as
SERVER_NAMESentries) without any manual action; disabled by default, enable in Settings → Maintenance → Catalogue - Change notifications (option) — Discord/Apprise alert sent on each refresh when servers are added to or removed from the catalogue, with per-provider detail (+N/−N); enable in Settings → Notifications
-
3 import modes in Settings:
- All providers — imports servers from every provider available in the local Gluetun catalogue, or from the GitHub fallback
- Chosen provider — imports only the servers of a provider selected manually
- Active provider — automatically detects the provider configured in your Gluetun and imports its servers only — for each mode, an option to run a full benchmark immediately after import (using the configured method in Settings, across all servers in the list)
-
All filter types — each server is imported with its full attributes:
SERVER_NAMES,SERVER_COUNTRIES,SERVER_CITIES,SERVER_REGIONS,SERVER_HOSTNAMES -
Multi-filter selection from
/servers— select servers by freely mixing filter types (e.g. names + countries + cities at the same time); Companion applies the right filter in Gluetun and changes the filter type on the fly if needed ⚠️ ProtonVPN — When the Gluetun container's/gluetunvolume is available, the Catalogue usesservers.jsonand can therefore show the Premium servers actually loaded by Gluetun, including P2P/Streaming/hostname metadata. Without that volume, the GitHub fallback may still be limited to public data.
Prerequisites — the catalogue sidecar works without extra configuration. To enrich the catalogue with the data actually loaded by Gluetun, Companion tries to mount the Gluetun container's /gluetun volume read-only; otherwise outbound HTTPS access is enough for the GitHub fallback.
-
Gluetun network containers (auto-managed) — running containers using
network_mode: service:gluetunare detected and recreated automatically after each switch, including those already stuck in a dead namespace (left over from a previously failed switch). Intentionally stopped containers stay stopped. Containers in a different Compose stack from Gluetun are also handled if their directory is accessible from Companion or if theircom.docker.composelabels are present. Orphan detection is limited to containers referencing a known former Gluetun (ID history kept in the database) — Companion never touches dependents of another VPN or an unrelated stack - Containers to restart after switch — ordered list (drag & drop), applied to manual and automatic switches, pools and failover; containers sharing Gluetun's network namespace are detected, recreated and verified automatically without duplicates
- Pause during benchmark — list of containers (torrent, Usenet…) stopped before the benchmark starts and automatically restarted when it ends, even on error
- Automatic Docker image updates (option) — at switch time, Companion can update images before restarting containers: Gluetun itself, auto-managed network containers, post-switch containers and benchmark-paused containers; togglable per container from Settings
- Multiple clients — configure one or more qBittorrent or rTorrent/ruTorrent clients in Settings → BitTorrent; each client can be a tracker source, even if its container is also stopped during benchmarks
- Persistent discovery — Companion fetches tracker URLs from loaded torrents, deduplicates them, then displays a domain-derived name, source clients, torrent count, last check and success rate; sortable by name or result
- Passkeys hidden — private passkeys and tokens are stripped from detected URLs before storage/display, including query-string keys and token-like path segments
- Per-URL control — each tracker can be enabled or ignored individually for future checks; the list also provides Check all and Uncheck all actions to quickly prepare a focused selection
- VPN compatibility score — either every discovered URL or checked trackers only are checked through the VPN path; by default, 80% success is enough to consider the server compatible, avoiding false negatives when a single tracker is down
- Optional switch criterion — when enabled, a benchmarked server below the tracker threshold is excluded from the auto-switch pick; pools ignore servers already known as tracker-incompatible
-
Per-provider port forwarding — declare AirVPN/manual, Gluetun-native (
/v1/portforward) or custom rules in Settings → Port Forwarding; when automation is enabled, Companion applies the current provider's rules after every switch (manual, benchmark, pool rotation), resynchronizes qBittorrent or rTorrent (beta) and runs the configuredon_port_changehooks; a periodic check also catches port renewals that happen without a container restart
-
Built-in AirVPN server picker — + Add AirVPN servers button on the Servers page: live data from
airvpn.org/api/status/(5-min server-side cache), four tabs — full searchable list, geographic distribution by country, Recommended tab (load < 70 %, bandwidth ≥ 5 Gbit/s) and Changes tab (newly detected servers, disappeared servers, load shifts, top 5 healthiest countries); multi-select, one-click add -
Visible and filterable AirVPN bandwidth — Companion stores the capacity advertised by AirVPN (
bw_max) separately from benchmark results: sortable/filterable column in/servers, filter in the AirVPN import modal, badges on the dashboard, history, pool rotations and switches. This is provider metadata, not a measured speed result. -
Avoid loaded AirVPN servers (optional, dedicated to AirVPN) — at benchmark start, AirVPN servers of type
SERVER_NAMESwhose load or user count exceeds a configurable threshold are automatically skipped; data from the AirVPN cache (updated every 5 min); servers without AirVPN data are never excluded; thresholds configurable in Settings → Measure → Which servers are allowed - New AirVPN server detection (optional) — compares the AirVPN API with your configured servers every 24 h; badge and dismissable banner on the Servers page + Changes tab in the add modal; Discord/Apprise notification with optional mention
- Per-server confidence score — 🟢/🟡/🔴 indicator on the Servers page and in History; based on measurement count and result variability; factored into the automatic selection score (light weighting)
-
Hourly patterns (
/history/patterns) — 0h–23h bar chart showing average speed by hour of day, color-coded by relative performance; best and worst hour displayed; helps identify server saturation windows -
Sortable columns — click table headers in
/historyand/serversto sort; clicking again reverses the order; ▲/▼/⇅ visual indicators; sort persists across pages - On-demand test of a single server from the UI without waiting for the next cycle
- CSV export of the full history
- Web UI dark/light/auto, FR/EN — auth, dashboard with sparkline, paginated history, charts, switches page with Mbps gain and connection time
-
Server detail panel — click a server name in
/servers: aggregate stats (average speeds, latency, peak, test count), sparkline of the last 30 tests, recent results and actions (test, switch, full history) in a side panel - Getting-started checklist — dashboard card guiding the install (VPN profile → server import → first benchmark), disappears once setup is complete
-
Column picker — hide unneeded columns on
/servers(preference kept per browser) - Settings search — search field filtering cards across all tabs with a per-tab match counter
- VPN provider logos — shown next to server names throughout the UI and in the catalogue (bundled SVGs + server-side cached favicons — the browser never contacts a third-party service)
- Global test banner — visible on every page during a test: test type, current server, progress %, estimated time remaining and a Stop button (state persists across page reloads)
- Contextual notifications — 12 independently-configurable alert types (VPN outage and emergency failover, benchmark start/complete, auto/manual switch, auto-exclude, benchmark with no results, quick check result, pool rotation, new AirVPN servers, catalogue changes, optimal window change) via Discord webhook (rich embed) and/or Apprise (Telegram, ntfy, Gotify, Slack, Pushover…); severity levels 🔴/🟡/🔵; global Discord mention with configurable severity threshold
- Automatic purge of SQLite history with configurable retention (in days)
-
/healthzendpoint unauthenticated, for Docker healthchecks -
/metricsendpoint in Prometheus format — throughput, latency, switches, active server; optionally protected by Bearer token; Grafana-compatible -
REST API
/api/v1/protected by Bearer token — VPN status, server list, history, switches, trigger full or quick benchmark; designed for Home Assistant, n8n, bash scripts -
Structured JSON logs optional via
LOG_JSON=1(Loki/Grafana compatible) - SQLite database (WAL) — no external dependencies
Repository · Issues · Releases
Français
- Compatibilité
- Démarrage rapide
-
Fonctionnalités
- Mesure de performances
- Résolveurs DNS observés
- Sélection & bascule automatique
- Pools de rotation
- Multi-provider (WireGuard & OpenVPN)
- Catalogue de serveurs Gluetun
- Gestion des containers Docker
- Contrôle trackers BitTorrent
- AirVPN
- Analyse & historique
- Interface & notifications
- Intégration & infrastructure
- Variables d'environnement
-
Fonctionnement
- Mode Sidecar (défaut)
- Mode Proxy HTTP (optionnel)
- Containers à redémarrer après bascule
- Containers à stopper pendant le benchmark
- Contrôle des trackers BitTorrent via le VPN
- Clients BitTorrent et découverte des trackers
- Inventaire des ports forwardés VPN
- Bandeau « Test en cours » et bouton Arrêter
- Sélecteur de serveurs AirVPN
- Vérification rapide avant benchmark (option)
- Optimisation horaire (option)
- Sélection intelligente du benchmark (recommandée pour les gros catalogues)
- Serveurs autorisés avant benchmark (option)
- Éviter les serveurs AirVPN chargés (option, dédié AirVPN)
- Écoute Docker events
- Score de confiance par serveur
- Profils d'usage
- Profils VPN (WireGuard & OpenVPN)
- Pools de rotation
- Score de sélection — composantes de stabilité
- Vue patterns horaires (/history/patterns)
- Détection de nouveaux serveurs AirVPN
- Notifications contextuelles
- Jitter & Packet Loss
- Endpoint Prometheus /metrics
- REST API
- Cycle automatique vs déclenchement manuel
- Dashboard Grafana
- Workflows automatisés
- Notes
- Sécurité
- Crédits
- Licence
English
- Compatibility
- Quick start
- Features
- Environment variables
-
How it works
- Sidecar mode (default)
- HTTP proxy mode (optional)
- Containers to restart after switch
- Containers to pause during benchmark
- BitTorrent tracker checks through the VPN
- BitTorrent clients and tracker discovery
- VPN forwarded port inventory
- "Test running" banner and Stop button
- AirVPN server picker
- Quick check before benchmark (option)
- Time optimization (option)
- Smart benchmark selection (recommended for large catalogues)
- Allowed servers before benchmark (option)
- Avoid loaded AirVPN servers (option, dedicated to AirVPN)
- Docker events listener
- Per-server confidence score
- Usage profiles
- VPN profiles (WireGuard & OpenVPN)
- Rotation pools
- Selection score — stability components
- Hourly patterns view (/history/patterns)
- New AirVPN server detection
- Contextual notifications
- Jitter & Packet Loss
- Prometheus /metrics Endpoint
- REST API
- Automatic cycle vs manual trigger
- Grafana dashboard
- Automated workflows
- Notes
- Security
- Credits
- License