-
-
Notifications
You must be signed in to change notification settings - Fork 2
How it works
Benchmark cycle (every X hours)
├─ "Pause bench" containers stopped (torrents, Usenet…)
├─ Pull ghcr.io/aerya/gluetun-companion-sidecar:latest
│ (once per cycle, image kept cached; best-effort: falls back to the
│ cached image if the registry/DNS is momentarily unavailable)
└─ For each enabled server:
1. Start gluetun-companion-test
(clone of your Gluetun, configured for the target server)
2. Start gluetun-companion-sidecar
(network_mode: container:gluetun-companion-test)
3. Wait for VPN via /health polling (configurable timeout)
4. Speed test inside the VPN tunnel (configurable engine):
- Dual (default): Ookla + librespeed in parallel, iperf3 as fallback
- Ookla only, librespeed only, or iperf3 only
→ DL, UL, latency recorded per source
5. Stop + remove the test containers (sidecar image kept cached)
→ Auto-retry on failure, global timeout per server
→ Auto-disable after N consecutive failures
└─ Weighted score (65% current cycle + 35% exponential history)
└─ Switch real Gluetun to the best server (one single restart)
└─ "Post-switch" containers recreated (network namespace included)
└─ "Pause bench" containers restarted (guaranteed — finally block)
└─ Discord / Apprise notification (if configured)
Available test engines (Settings → Measure → Sidecar Mode):
- Dual (default) — Ookla + librespeed in parallel; results from both sources stored separately
- Ookla only — official Speedtest.net CLI, rarely blocked by VPN IPs
- librespeed only — librespeed-cli, public librespeed.org servers (HTTP)
- iperf3 only — direct TCP to public iperf3 servers (often blocked by VPN IPs)
Fallbacks:
- iperf3 as last resort if all primary sources fail (enabled by default)
- HTTP proxy fallback if sidecar fails entirely (disabled by default)
⚠ Simultaneous connection: sidecar mode uses one extra VPN connection slot for the entire benchmark duration. Check your provider's limits (AirVPN: 3–5 depending on plan). Companion runs sidecar tests one at a time and waits 180 s by default after container cleanup (
sidecar_disconnect_wait_seconds) so the provider can close the VPN session before the next server starts. This is the main driver of cycle duration: with N servers a cycle takes at least N × this delay. If your plan allows several simultaneous connections (AirVPN: 3–5), lower it significantly (60 s or less) in Settings → Measure to shorten cycles; raise it if you see "too many connections" errors. The sidecar image is pulled once per cycle then reused from cache: less load on the registry/DNS, and a test no longer fails (nor switches the server) on a transient DNS hiccup.
Benchmark cycle (every X hours)
└─ For each enabled server:
1. Write docker-compose.override.yml
2. docker compose up -d ← real Gluetun restarts
3. Wait for VPN via HTTP proxy polling
4. Optional TCP warm-up (2 s, not counted)
5. Download from N endpoints → median Mbps
6. Upload → Mbps
7. Latency TTFB → median ms
└─ Weighted score → switch → notification
Enable via Settings → Measure → Sidecar Mode → toggle off.
In Settings → Decide → Containers to restart after switch: ordered list of containers recreated after every VPN switch, whatever its trigger. In Compose mode, Companion uses docker compose up -d --force-recreate; in Unraid/DockerMan mode, it recreates containers through the Docker SDK. Services using network_mode: service:gluetun are detected separately, reattached to the new namespace ID and verified; a Docker event also repairs this attachment after an external Gluetun recreation. Drag & drop to reorder.
The active server shown on the dashboard and returned by the API is resolved from the tunnel endpoint actually selected by Gluetun and its provider catalogue. SERVER_* variables remain selection filters, but a candidate list is no longer presented as the connected server. Changes observed outside Companion are added to switch history.
After every successful benchmark, Companion computes and stores the best server for the active profile even when automatic switching is disabled. End-of-benchmark notifications and history therefore no longer leave “Best server” empty in measure-only mode.
In Settings → Measure → Containers to pause during benchmark: list of containers stopped before the benchmark and restarted after — in all cases, even if the benchmark crashes. If a container is in both lists, the pause list takes priority (no duplicate restart). Useful for qbittorrent, sabnzbd, nzbget, transmission.
In Settings → BitTorrent, Companion can verify whether the trackers actually used by your torrents are reachable from the VPN server being tested or selected. The goal is not to perform a full real announce for every torrent, but to verify useful connectivity with four levels:
According to the official Gluetun DNS documentation, Gluetun enables BLOCK_MALICIOUS=on by default. Some announce URLs may therefore be blocked by its DNS lists even when the tracker is available. Under Settings → BitTorrent → Gluetun DNS filtering, Companion can keep this protection enabled while allowing specific domains through DNS_UNBLOCK_HOSTNAMES, or disable BLOCK_MALICIOUS entirely as a last resort. The setting is written to docker-compose.override.yml, applied immediately by recreating Gluetun, and preserved across subsequent switches. Disabling it globally reduces DNS protection for every container sharing Gluetun's network; a targeted exception is recommended.
- DNS — the tracker domain can be resolved.
- Port — the TCP/UDP tracker port responds.
-
Tracker endpoint — the
/announceURL or UDP tracker handshake responds. HTTP400,401,403orinvalid requestresponses can still count as reachable: the tracker rejected the test request, but the endpoint is accessible. - Aggregated score — if the percentage of reachable trackers is above the configured threshold (80% by default), the VPN server is considered compatible.
This threshold avoids false negatives: a private or public tracker can be temporarily down without making the VPN server bad. Companion stores per-URL history so it can gradually distinguish globally unavailable trackers from trackers blocked only on specific VPN paths.
Two separate toggles are available in Settings → BitTorrent:
- Enable tracker checks during VPN verification runs discovery before benchmarks, then checks either every discovered URL or checked URLs only for each server, depending on the selected scope.
- Require an OK tracker result for automatic switches and pools turns that score into an eligibility criterion: during a benchmark, servers below the threshold are excluded from the final pick; in pool rotation, servers already known below threshold are ignored, while never-tested servers remain candidates.
The Servers page shows a sortable Trackers column with the latest known result per server (OK, below-threshold percentage, or — when never tested). This makes compatible and problematic servers easy to spot.
HTTP/HTTPS trackers are checked through Gluetun's HTTP proxy when configured. UDP trackers require Companion to be able to send UDP from the VPN path; if your installation only exposes the HTTP proxy, UDP URLs can still be listed and managed, but real UDP checks depend on your network topology.
Companion can manage multiple BitTorrent sources: for example one main qBittorrent instance, another qBittorrent dedicated to cross-seed, and an rTorrent/ruTorrent instance. Each configured client contains:
- type:
qBittorrentorrTorrent / ruTorrent RPC2; - API/WebUI URL;
- credentials;
- optional Docker container name;
- category or tag filters;
- options to include/exclude paused torrents or private torrents.
For qBittorrent, Companion uses the Web API: torrent list, then the trackers endpoint for each hash. For rTorrent/ruTorrent, Companion uses XML-RPC/RPC2 and fetches trackers per torrent.
Discovery always runs before stopping containers configured in "Containers to pause during benchmark". So if qbittorrent or rutorrent is stopped during measurement, Companion uses the already cached tracker list. The UI derives a readable tracker name from each domain, shows its cumulative success rate, and supports sorting by name or result. URLs can be enabled or ignored one by one, or all at once with Check all / Uncheck all, when the “checked trackers” scope is selected. URLs are normalized without passkeys (?passkey=..., authkey, token, private path segments, etc.) so secrets are not exposed in the interface.
In Settings → Port Forwarding, Companion manages incoming ports required by BitTorrent clients per VPN provider. Three states are available:
- Disabled — rules remain stored but are not applied.
- Manual active — rules can be declared, checked and synchronized on demand.
-
Automatic active (default once port forwarding is enabled; can be turned off) — when Gluetun switches to another VPN server or provider (manual switch, benchmark or pool rotation), Companion automatically applies the current provider's rules. This also covers ProtonVPN switches to another server of the same provider, where the NAT-PMP port may change. After a Docker-detected Gluetun reconnection, Companion also rereads the native port and propagates it when needed. Finally, a periodic check (every 5 min) compares the native
/v1/portforwardport to the last applied port: if Gluetun renewed the port without a container restart (e.g. NAT-PMP renewal), the rules are re-applied automatically.
Each entry contains:
- readable name;
- provider (
AirVPN,ProtonVPN,Custom WireGuard, etc., orManual); - mode (
ManualorGluetun native); - manual port, optional in native mode;
- protocols
TCPand/orUDP; - optional linked BitTorrent client;
- optional
on_port_changecommand; - free-form note.
For a manual/static rule, the UI checks:
- whether the port is present in
FIREWALL_VPN_INPUT_PORTS; - whether the port is present in
FIREWALL_INPUT_PORTS; - whether the port is published on the Gluetun Docker container, per protocol;
- qBittorrent listen port when the entry is linked to a qBittorrent client.
For a Gluetun native rule, these static ports are not required. Companion instead checks that the Control Server responds, that a dynamic port is assigned, and that the linked client uses that same port. The UI therefore shows Gluetun native port, Control Server, and not required instead of the FIREWALL_* and Docker checks.
The Sync button updates the linked client's listen port: qBittorrent through the Web API (/api/v2/app/setPreferences + read-back verification), or rTorrent via XML-RPC (network.port_range.set + read-back — beta support, implemented against the XML-RPC spec but not yet validated on a live rTorrent instance; the on_port_change hook remains available as a fallback). In Gluetun native mode, Companion first reads the Gluetun Control Server (GET /v1/portforward) and then pushes the returned port to the client.
Testing reachability from the Internet: each rule's Test from Internet button performs a real TCP connection from Companion to VPN_public_IP:port. Since Companion egresses through your ISP connection (not the VPN tunnel), this exercises the actual inbound path: Internet → VPN provider → Gluetun → client. TCP only — UDP has no handshake and cannot be verified this way. The configuration indicators (firewall, Docker publishing, listen port) remain local checks; this button is the only one proving real reachability. For a manual external double-check: canyouseeme.org or yougetsignal.com (VPN public IP and port must be typed by hand — these sites cannot be pre-filled).
To enable Gluetun native support, expose its Control Server. The internal port remains 8000, but the host port may differ: with 8043:8000, the URL from Companion is for example http://host.docker.internal:8043. If your environment requires adding the Control Server to FIREWALL_INPUT_PORTS, enter the internal port 8000, not 8043.
Leave the URL field empty when Docker autodetection works. With a custom mapping, Portainer, or Synology, enter it explicitly: the URL must be reachable from the Companion container, not only from the host or a browser. If Gluetun uses apikey authentication, enter the same value in X-API-Key. Companion uses /v1/portforward as the primary source and retries the legacy /v1/openvpn/portforwarded endpoint when needed.
# From the Docker host
curl -i http://127.0.0.1:8043/v1/portforward
# From Gluetun
docker exec gluetun wget -S -O- http://127.0.0.1:8000/v1/portforwardThe expected response is HTTP/1.1 200 OK with a port. A 401 or 403 means authentication was rejected. The recommended method is an API key generated with docker run --rm qmcgaw/gluetun genkey, configured in Gluetun, and copied to Companion. On a fully trusted LAN, HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE={"auth":"none"} is possible but strongly discouraged by Gluetun; never publish the Control Server to the Internet this way.
ProtonVPN assigns a random NAT-PMP port which may change on every connection or renewal. Do not enter a fixed port or publish that port in the Docker Compose file. In the ProtonVPN profile, enable Port forwarding; Companion then writes VPN_PORT_FORWARDING=on for that profile and can restrict selection to P2P / port-forwarding servers with PORT_FORWARD_ONLY=on. Other Gluetun server types (Streaming, Secure Core, Tor, Free) can also be selected from the profile or catalogue when useful. Then configure a rule using provider ProtonVPN, Gluetun native mode, and the relevant qBittorrent client. Companion:
- reads the current port from
GET /v1/portforward; - sends it to qBittorrent through
/api/v2/app/setPreferences; - reads qBittorrent preferences back to confirm the change;
- checks every 5 minutes whether Gluetun renewed the port and injects the new value when needed;
- repeats after a Gluetun reconnect, a switch to ProtonVPN or a switch between ProtonVPN servers.
With ProtonVPN over OpenVPN, the OpenVPN username must also carry the +pmp suffix. ProtonVPN over WireGuard does not use this suffix. Gluetun native integrations open the dynamic port on the VPN side themselves, so FIREWALL_VPN_INPUT_PORTS, FIREWALL_INPUT_PORTS, and a static Docker port mapping are not required for this port.
For AirVPN, Companion does not create the port in the AirVPN panel. The expected flow is:
- reserve the port in the AirVPN panel;
- publish the port on Gluetun, for example
19975:19975/tcpand19975:19975/udp; - add the port to
FIREWALL_INPUT_PORTSandFIREWALL_VPN_INPUT_PORTS; - declare the port in Companion;
- link the port to the relevant qBittorrent client or add an
on_port_changecommand; - enable automatic application if rules should follow VPN provider changes.
For rTorrent/ruTorrent, simply link an rTorrent-type client to the rule: XML-RPC synchronisation applies automatically (beta — see above). For other clients, personal WireGuard servers or any specific need, use on_port_change to call a controlled script or command. Available variables are {port}, {provider}, {name}, {protocols} and {client}. Example:
/compose/hooks/update-rtorrent-port.sh {port}A Custom WireGuard rule can therefore cover a personal WireGuard server: the port can be declared manually, or handled by an external hook, and Companion runs the command when the rule becomes applicable.
While any test is active (full benchmark, continuous observation, quick proxy test, sidecar, pool rotation), a green banner appears at the top of every page showing the test type, the server under test, the progress in % (bar + percentage) and an estimated time remaining based on the average duration of servers already tested this cycle.
A Stop button is available for all modes:
- Benchmark / Observation / Sidecar — stops after the current server (≤ 2 seconds).
- Quick test (proxy) — stops after the current sample (≤ one sample duration, typically 8 s).
- Pool rotation — stop signal sent; the rotation completes cleanly.
The stop request is persisted server-side: reloading or leaving the page does not reset it — the banner stays on "Stop requested…" until the test actually stops.
On Servers → + Add AirVPN servers: a modal loads live data from the AirVPN API (5-min server-side cache). Four tabs:
- Servers — full list with color-coded load bar (green/orange/red), user count, health status, sortable columns, real-time search
- By country — collapsible sections per country with flag emoji, 🏆 Best badge on the least-loaded server, "Select all" button per country
- ⭐ Recommended — servers matching the pre-selection criteria: load < 70 % and AirVPN advertised bandwidth ≥ 5 Gbit/s; green badge showing the count. Real peering between your access link and the VPN server is not known at import time: Companion approximates it later through benchmarks (latency, jitter, loss, throughput).
- ↔ Changes — diff since the last check: newly appeared servers (selectable for instant add), disappeared servers, load shifts ≥ 10 % (with ↑↓ arrow and delta badge), top 5 countries ranked by healthy-server percentage then average load
Servers already in the database are grayed out with their checkbox disabled. The search bar filters all tabs simultaneously. Multi-select, one-click add.
Enable via Settings → Measure → Avoid unnecessary tests.
When enabled, each cycle starts with a speed test of the currently active server only — before stopping any containers or restarting Gluetun:
- Within threshold (default ±15%): the full benchmark is skipped. No containers are stopped, Gluetun is not restarted, no VPN interruption. Cycle completes in seconds.
- Outside threshold: the full benchmark runs normally — all servers are tested, the best one is selected.
Implementation: the quick check runs exclusively via the Gluetun HTTP proxy — no sidecar container is created, no VPN reconnection wait. Result in 10–15 seconds.
This is ideal for frequent scheduling intervals (e.g. every 2–3 hours) where you want a sanity check without the cost of a full benchmark every time.
The threshold is configurable (1–100 %). A value of 15 means: if the current speed is between 85 % and 115 % of the last known result, the full benchmark is skipped.
Enable via Settings → Measure → Optimize the time.
Companion analyses the test history to compute, for each hour of the day (0–23), the average download speed and coefficient of variation (CV = σ/μ). An hour with high speed and low variance is a good benchmark window — measurements are representative and reproducible there.
Score per hour = avg_speed × max(0, 1 − CV/100)
- 🟢 Good window — score ≥ 70 % of the maximum
- 🔴 Avoid — score < 50 % of the maximum
When it's useful: if your ISP throttles bandwidth at certain hours (e.g. evening congestion), or if the VPN servers you use are significantly more loaded at certain times of day. In that case, benchmarking during off-peak hours gives measurements that better reflect real-world usage.
When it adds no value: if your network is stable 24/7 and your VPN servers have a relatively constant load, this option won't make a practical difference. It doesn't change which server is fastest — only when you measure it.
Requirements: at least 6 tests in at least 8 different hour slots. Results stabilise after several days of automatic benchmarks. Below this threshold, per-hour averages are too sensitive to outliers to be reliable.
Auto-shift (sub-option): if a scheduled cycle falls on an unfavorable hour, the benchmark is deferred by up to 3 h to the next favorable window. If none is found within that delay, the benchmark runs immediately. Once complete, the scheduler resumes its normal interval.
Optimal window stability: the best hour is only confirmed and notified after two consecutive cycles pointing to the same hour. This prevents false alerts caused by statistical noise (previously, a single exceptional measurement was enough to trigger a window change notification).
This option complements the automatic cycle — it does not replace it. The configured interval remains the reference; the adaptive shift only adjusts the next trigger if the hour is deemed unfavorable.
Enable via Settings → Measure → How many servers to test.
Two modes are available:
- Test everything — exhaustive mode: every compatible active server participates in the cycle. Useful to build an initial baseline, but very long with catalogues such as NordVPN.
- Smart selection — recommended mode: Companion tests the N best known servers for the active usage profile, adds a few never-tested servers, then refreshes a few results older than X days.
Configurable quotas are under Advanced smart selection options:
- Known top — number of already-measured servers to keep according to the usage profile.
- New — number of never-benchmarked servers to explore in each cycle.
- Old after d + Refresh — minimum age and number of old results to recheck.
Set a quota to 0 to disable that part. The dashboard reminds you which mode is used, the estimated server count, and the test mode (sidecar or proxy) before a manual launch.
Enable via Settings → Measure → How many servers to test → Pyramidal continuous observation.
This mode makes usage profiles serious without running a huge benchmark every time. It turns the automatic cycle into progressive data collection:
- Exploration — tests a batch of never-measured servers, rotating through the list day by day.
- Confirmation — retests servers that already have a few measurements, up to the “confirmed” threshold.
- Finalists — focuses repeated measurements on the best candidates that do not have enough history yet.
- Refresh — rechecks a few mature servers whose measurements have become old.
In continuous observation, Companion does not run quick check, does not stop the containers configured in “Containers to stop during benchmark”, and does not automatically switch servers. The goal is to build useful history, not to disturb normal usage.
The dashboard shows live observation state: current server, next server, cycle progress, the latest Companion activity lines, and a direct link to /history to review stored results. An internal watchdog regularly checks that observation resumes after a restart or when the regular automatic benchmark cycle is paused.
If the regular automatic cycle is also enabled, it keeps a different goal: compare the configured selection at a regular interval and, if auto-switch is enabled, move Gluetun to the best server. When a scheduled cycle becomes due during continuous observation, Companion pauses observation, runs the normal full benchmark (including pausing configured containers), then resumes observation through the watchdog. Pool rotations and manual tests (quick or full) also have priority: they interrupt the current observation run, execute, then observation resumes if needed.
Usage profiles should not be treated as instant magic: with one or two measurements, they are only an indication. They become genuinely meaningful once servers have several full benchmarks, ideally at different hours.
Enable via Settings → Measure → Which servers are allowed.
These rules reduce the list before a full benchmark. Excluded servers remain visible in /servers and can still be tested manually.
By default, the benchmark tests all enabled entries in /servers, regardless of their Gluetun type. With Allowed Gluetun types, you select exactly which types will participate in each cycle:
| Type | Gluetun variable | Typical use |
|---|---|---|
| Name | SERVER_NAMES |
Individual AirVPN servers, precise name |
| Country | SERVER_COUNTRIES |
Broad geographic selection |
| City | SERVER_CITIES |
Precise geographic selection |
| Region | SERVER_REGIONS |
Region / state |
| Hostname | SERVER_HOSTNAMES |
FQDN hostname |
- All checked (default): identical behaviour — no filtering.
-
Some checked: only entries of the checked types are tested; the others remain in
/serversand can be tested individually via the "Test now" button.
Useful if you have
country/regionentries as fallback but only want to test them occasionally, without including them in every automatic cycle.
Avoid loaded AirVPN servers (option, dedicated to AirVPN)
Enable via Settings → Measure → Which servers are allowed → Avoid loaded AirVPN servers.
When you have added a large number of AirVPN servers (type SERVER_NAMES), a full benchmark cycle can take a very long time. This pre-filter lets you automatically skip overloaded servers at the start of each cycle:
-
Max load (%) —
0= disabled. E.g.70→ servers showing more than 70% load in the AirVPN cache are skipped for this cycle. -
Max users —
0= disabled. E.g.30→ servers with more than 30 connected users are skipped.
The two thresholds are independent and cumulative — a server is skipped as soon as at least one enabled threshold is exceeded.
Data source: the internal airvpn_snapshot table, updated every 5 minutes from the airvpn.org/api/status/ API. No extra API call is made at benchmark launch.
Servers without data: a name-type server with no entry in the snapshot (non-AirVPN provider, server absent from the API) is never filtered — it is always included in the benchmark.
Scope: this filter only applies to name-type servers (AirVPN). Entries of type country, city, region, hostname are never affected.
Skipped servers remain in
/servers, can be tested manually, and will be candidates again in the next cycle if their load has dropped in the meantime.
A daemon thread starts with Companion and continuously monitors the Docker event stream filtered to the Gluetun container. On every start event received:
Docker "start" event received on the Gluetun container
├─ Companion-initiated restart? (180 s suppression window) → silently ignored
├─ Cooldown active? (5 min since last trigger) → ignored
├─ Benchmark already running? → ignored
└─ OK — schedule a deferred quick check
1. Wait N seconds (= "Connection wait" setting)
to allow the VPN to reconnect
2. Quick check via HTTP proxy on the active server
├─ VPN not ready yet (no proxy response)
│ → log warning, abort
├─ No baseline result in the database yet
│ → result saved as new baseline, done
├─ Speed within ±N% threshold
│ → log OK, done
└─ Drift detected (speed outside threshold)
├─ Auto-switch enabled → immediate full benchmark
└─ Auto-switch disabled → log warning only
Companion restart suppression: when Companion switches to a server (switch_server()), it opens a 180-second suppression window. Any start event received during that window is ignored — this prevents an infinite loop where Companion would trigger a quick check after every switch it just initiated.
Badge in history: tests triggered by a Docker event are tagged docker_event in the database. A dark auto badge appears on the corresponding row in the History page (/history), with an explanatory tooltip.
Requirements: the Docker socket (or Tecnativa proxy) must be accessible from Companion, and the GLUETUN_CONTAINER variable must match the exact name of the Gluetun container.
A color indicator is shown on the Servers page (Confidence column) and in History for each server. It reflects how reliable the accumulated measurements are.
| Level | Conditions |
|---|---|
| 🟢 High | ≥ 5 measurements and variability < 40 % |
| 🟡 Moderate | 2–4 measurements or variability 40–70 % |
| 🔴 Low | ≤ 1 measurement, variability > 70 % or consecutive failures |
Variability (coefficient of variation) is the standard deviation of speeds divided by the mean: 0 % = identical results every test, 100 % = very scattered results. Quick check tests (proxy_qc) are excluded from the calculation.
The score lightly influences automatic server selection: HIGH × 1.0 · MEDIUM × 0.95 · LOW × 0.85 applied to the weighted score.
Companion provides 6 usage profiles selectable from the Servers page (pill bar) or from Settings → Decide → Usage profile.
The active profile determines how the best server is selected at the end of each benchmark cycle, by weighting the measured metrics differently.
Important: a usage profile is only reliable when enough history exists. At first, Companion can mostly compare available throughput; latency, jitter, packet loss, upload, DDL single-stream speed, and stability become truly discriminating only after several full benchmarks per server. To build that history without looping over the whole catalogue, use pyramidal continuous observation in Settings → Measure.
| Profile | Primary criterion | Typical use |
|---|---|---|
| Balanced (default) | Existing weighted score (speed + history + stability) | General use — identical behavior to before |
| Gaming | Low latency + low jitter | FPS, MMO, competitive games |
| BitTorrent | Maximum multi-stream upload | qBittorrent, Transmission, Deluge |
| DDL (single-stream) | Single-stream download throughput | Usenet (SABnzbd), direct downloaders (JDownloader) |
| Download (multi-stream) | Maximum multi-stream download | Radarr/Sonarr, large file transfers |
| Video streaming | Stable throughput + low jitter | Jellyfin, Plex, direct play |
Algorithm: for each result from the current benchmark cycle, Companion computes the _weighted_score (speed + history + stability), then min-max normalises [0,1] all results on each axis. The weighted combination of normalised scores determines the best server for the active profile. The Balanced profile reproduces the exact previous behavior — no regression.
DDL profile and single-stream test: the DDL profile leverages an additional metric, single-stream download speed (dl_single_mbps), measured after the main test (VPN connection already established, no reconnect overhead). This test is optional and disabled by default — enable it via Settings → Measure → Speed measurement → Single-stream test (DDL).
Servers page: the profile pill bar displays the best server for the active profile (computed from historical averages). The recommended server is highlighted with a 🏆 badge on its row (hidden in Balanced mode).
Explainable score: each server in the table view has a 📊 button (chart icon) next to its name. Clicking it opens a popover showing each metric's contribution to the final score — download speed, upload, latency, jitter, packet loss — as weighted progress bars with the raw measured values. Only metrics actually used by the active profile are displayed.
Scoring time window: by default, the averages used to rank servers are computed over the last 30 days. This can be adjusted in Settings → Decide → Scoring window: 7 d, 14 d, 30 d, or all data. A shorter window favours recent performance; a longer window smooths out one-off spikes.
Outlier detection: enable in Settings → Decide → Filter outlier values. When active, isolated measurements that are clearly out of range are excluded from averages and scoring — they remain visible in the history. Concrete example: if a server normally delivers 80–100 Mbps but one exceptional test returns 5 or 200 Mbps (transient spike, momentary saturation, failed test), that value is excluded from calculations. The IQR method automatically determines the normal range per server and per metric (speed, latency, jitter…) with no threshold to configure. Requires at least 4 measurements per server to take effect.
VPN profiles let you manage multiple VPN providers or identities — over WireGuard as well as OpenVPN — in a single Companion instance, with automatic optimised switching between them. All 24 providers from the Gluetun wiki are integrated (see the provider table).
In Settings → VPN profiles:
- Choose a provider from the dropdown → credential fields appear dynamically based on what Gluetun requires for that provider
- If the provider supports both, choose the connection type (WireGuard or OpenVPN) — the fields adapt to the selected type
- Fill in the fields (private key, OpenVPN credentials, etc.) — fields marked 🔒 are encrypted before storage
- Name the profile (e.g. "Mullvad — Sweden", "PIA — OpenVPN US")
- The Active and Rotation allowed toggles include or exclude the profile from automatic cycles
Secret security: encrypted values are stored with the prefix
enc:in the database. They are only decrypted at the moment the Compose override is written or a sidecar container is launched — never exposed in logs or configuration exports.
WireGuard: two different keys — the main profile WireGuard private key is required to connect and switch Gluetun. The Sidecar private key is a second identity reserved for isolated benchmarks; entering it never replaces the main key.
Depending on the provider, an OpenVPN profile carries:
-
Credentials —
OPENVPN_USER/OPENVPN_PASSWORD(most providers: ExpressVPN, IPVanish, NordVPN, PIA, Surfshark, TorGuard, VyprVPN…); note that several providers use service credentials distinct from the website login (NordVPN, ProtonVPN, Surfshark, Windscribe) -
Client certificate and key — CyberGhost, VPN Unlimited and AirVPN (OpenVPN) additionally (or instead) require a client certificate and key: paste the base64 body as a single line, without the
BEGIN/ENDmarkers, into theOPENVPN_CERT/OPENVPN_KEYfields — no file mount needed -
Encrypted key + passphrase — SlickVPN and VPN Secure use an encrypted client key (
OPENVPN_ENCRYPTED_KEY) with its passphrase (OPENVPN_KEY_PASSPHRASE)
On switch, Companion writes VPN_TYPE=openvpn and the OPENVPN_* variables to the Compose override, blanking credentials from other providers/types to prevent any leak. In sidecar mode, OpenVPN profiles are tested with their own credentials (no dedicated sidecar key — most providers allow several simultaneous connections per account).
The Custom OpenVPN mode (VPN_SERVICE_PROVIDER=custom + VPN_TYPE=openvpn) covers any provider missing from the Gluetun catalogue. Under Settings → VPN profiles → Custom OpenVPN configurations, Companion can upload a .ovpn or .conf file, detect files already mounted in Gluetun, list them, and automatically create the matching profile.
The same host directory must be mounted in both containers:
# Gluetun Compose
services:
gluetun-airvpn:
volumes:
- /home/aerya/docker/gluetun/openvpn:/gluetun/openvpn:ro
# Companion Compose
services:
gluetun-companion:
volumes:
- /home/aerya/docker/gluetun/openvpn:/openvpn
environment:
- OPENVPN_CONFIG_DIR=/openvpn
- OPENVPN_CONTAINER_DIR=/gluetun/openvpnUploaded files therefore appear in Gluetun as /gluetun/openvpn/profile-name.ovpn. Detection can also inventory other .ovpn or .conf files already available below /gluetun, without docker exec.
As documented by Gluetun, any companion files referenced by the configuration (ca.crt, key, script, etc.) must also be mounted below /gluetun and referenced with absolute paths. If the remote directive contains a hostname, replace it with an IP address so Gluetun's startup firewall does not require an initial DNS resolution.
The Custom WireGuard provider is for Gluetun VPN_SERVICE_PROVIDER=custom setups, especially when you have one personal WireGuard server or a provider with no Gluetun server catalogue.
In this mode, Companion does not set any SERVER_* variable (SERVER_NAMES, SERVER_COUNTRIES, etc.). The custom profile fields describe the single WireGuard endpoint directly:
WIREGUARD_ENDPOINT_IPWIREGUARD_ENDPOINT_PORTWIREGUARD_PUBLIC_KEYWIREGUARD_PRIVATE_KEYWIREGUARD_ADDRESSES-
WIREGUARD_PRESHARED_KEYif your configuration uses one
The row added in Servers becomes only a statistics label, for example Personal server, Home-WG or VPS-Paris. It lets Companion attach benchmarks, history, Prometheus and Grafana metrics to that server without comparing it against other destinations.
Recommended setup:
- Create a Custom WireGuard profile in Settings → VPN profiles.
- Copy the values from your WireGuard
.conffile into the profile fields. - Add one entry in Servers with any clear label.
- Assign that entry to the Custom WireGuard profile.
- Let scheduled observation or benchmarks measure that server regularly.
On switch, Companion writes VPN_SERVICE_PROVIDER=custom, VPN_TYPE=wireguard and the WIREGUARD_* variables to docker-compose.override.yml, while leaving all SERVER_* variables empty.
If you use sidecar mode for WireGuard benchmarks, the most reliable setup is to give each WireGuard profile its own dedicated sidecar identity. Companion can also, as an advanced option, reuse the main profile WireGuard configuration.
This section only applies to WireGuard profiles: OpenVPN profiles are tested directly with their own credentials (the Dedicated sidecar key section is hidden for them).
Why this is recommended: sidecar test containers clone the environment of your main Gluetun container, including its WIREGUARD_PRIVATE_KEY. When a test container initiates a new WireGuard handshake using the same key from a different IP address, some VPN providers update the peer routing… and your main Gluetun tunnel may drop.
Why there is no global key: an AirVPN key cannot authenticate against Mullvad or Proton, and vice-versa. A shared sidecar key across multiple providers is inherently invalid — each profile must carry its own configuration.
Solution: in Settings → VPN profiles, edit each profile and fill in the Dedicated sidecar key section:
-
Sidecar private key — a new private key generated from the same provider as the profile (e.g.
wg genkeyfor providers that support it, or from your client account) -
Sidecar IP address — the IP address assigned to this key by your provider (CIDR format, e.g.
10.x.x.x/32) - Sidecar pre-shared key — only if your provider requires one
AirVPN / device case: exporting the same AirVPN device again normally returns the same PrivateKey, PresharedKey, and Address. To get a different triplet dedicated to the sidecar, create a second AirVPN device/peer, even if it represents the same physical home server.
Advanced option: enable Reuse the main profile WireGuard configuration if you accept the sidecar using the same WireGuard identity as the main Gluetun instance. This is convenient for providers that tolerate it, but it may disturb the main tunnel with others.
If a profile has neither a dedicated sidecar key nor the reuse option enabled, its servers are skipped in sidecar mode (no failure recorded — they are simply excluded from the cycle). If the proxy fallback is enabled, they automatically fall back to proxy mode instead.
On the Servers page:
- The Provider column shows the VPN profile assigned to each server
- If no profile is assigned, a dropdown lets you assign one directly from the table
- The
?profile=<id>filter (dropdown in the filter bar) limits the display to servers from a given profile or to unassigned servers (__none__) - Servers without a profile when at least one profile is configured are flagged as (orphan servers)
Benchmark cycle with VPN profiles
├─ Load and decrypt credentials (WireGuard or OpenVPN)
│ for each distinct profile_id in the server list
│ → in-memory cache for the duration of the cycle (decrypted secrets, not persisted)
└─ For each enabled server:
1. Retrieve extra_env from the associated profile
(VPN_SERVICE_PROVIDER, VPN_TYPE, WIREGUARD_* or OPENVPN_*)
2. Sidecar mode:
├─ OpenVPN profile → sidecar container launched with the profile credentials
│ (most providers allow several simultaneous connections)
├─ WireGuard profile with a dedicated sidecar key → sidecar launched with sidecar key
│ (prevents peer conflict with the main Gluetun tunnel)
├─ WireGuard profile allowing reuse → sidecar launched with main profile vars
└─ WireGuard profile with no sidecar key and no reuse → server SKIPPED for this cycle
(if proxy fallback enabled → tested in proxy mode instead)
3. Proxy mode: test via Gluetun HTTP proxy (no sidecar container)
└─ Select the best server according to the rotation policy:
├─ none → constrained to the profile of the currently active Gluetun server
├─ conditional → cross-profile switch if gain > threshold (default 10 %)
└─ free → global best across all profiles
└─ Gluetun switch:
→ writes VPN_SERVICE_PROVIDER + VPN_TYPE + credentials to the Compose override
(credentials from other providers/types are blanked)
→ docker compose up -d (single Gluetun restart)
| Mode | Behavior |
|---|---|
| none | Companion finds the best server within the currently active profile. If no results are available for that profile (all excluded, all orphaned), no switch occurs. |
| free | All tested servers are candidates — the global best is selected regardless of profile. |
| conditional | Benchmark is global, but a cross-profile switch only happens if score_global_best > score_best_in_current_profile × (1 + threshold/100). Otherwise the best server in the current profile is retained. |
The
conditionalthreshold is configurable from 1 to 100 % in Settings. A threshold of 10 % means: "only switch profiles if the gain exceeds 10 %".
Rotation pools let you switch to a server from a predefined group without triggering a full benchmark. Accessible from the Rotation page in the navigation bar.
In Rotation → New pool:
- Give the pool a name (e.g. "Gaming FR", "Fallback EU")
- Choose the selection mode:
- 🎲 Random —
random.choice()from the candidates - 🔄 Round-robin — alphabetical cycle with a persistent cursor between rotations
- 🏆 Best historical download — candidate with the highest historical average download speed
- 🎲 Random —
- Add one or more criteria to build the candidate servers:
-
All active servers— includes every enabled server in Companion -
Specific server— type the exact name; autocomplete suggests existing servers -
Gluetun filter type— choose the variable (SERVER_COUNTRIES,SERVER_NAMES, etc.) and optionally a value (empty = all servers of that type) -
VPN profile— all servers assigned to a specific WireGuard or OpenVPN profile -
Top N by metric— adds or restricts using the best historical download, jitter, packet loss or DNS metrics -
Minimum AirVPN bandwidth— adds AirVPN servers whose advertised capacity (bw_max) is at least the chosen value
-
- Choose how rules are combined:
- Add the results of each rule — each rule adds servers; duplicates are merged automatically.
- Keep only servers matching every rule — stricter, useful for "France + AirVPN profile + Top download".
- Add pool exclusions if needed: these servers remain active in Companion, but this pool will never pick them.
- Set an optional final limit: if specified, only the N best historical download speeds remain eligible after rules and exclusions.
- Configure the schedule: automatic rotation every N hours (disabled = manual only)
- Enable Measure after switch to record speed after each rotation. This measurement is not used to choose the server.
The preview updates in real time inside the modal: candidates before exclusions, excluded servers, usable servers and optional final limit.
Rotation triggered (manual or automatic):
1. Resolve candidates
├─ rules added together or intersected depending on the selected mode
├─ explicit pool exclusions removed
├─ known tracker-incompatible servers removed (if enabled)
└─ final limit by historical download speed (if set)
2. Pick target server (random / round-robin / best historical download)
3. switch_server() → write docker-compose.override.yml + docker compose up -d
└─ If a VPN profile is attached: inject VPN_SERVICE_PROVIDER, VPN_TYPE and WIREGUARD_* or OPENVPN_* into the override
4. Wait for VPN reconnection + recreate `network_mode: service:gluetun` containers
5. If post-switch measurement is enabled:
├─ Wait for VPN reconnection (connection_wait_seconds)
├─ Quick proxy test (proxy_qc)
└─ Record in speed_tests (test_trigger='pool_rotation')
6. Update pool state (last_rotated_at, next_rotation_at, last server, last speed/error, round-robin cursor)
7. Discord/Apprise notification (if enabled)
The scheduler checks every 5 minutes whether any pool has a pending rotation (next_rotation_at <= now). If a benchmark is running, the rotation is deferred to the next tick without modifying next_rotation_at.
Pool rotations and benchmarks share the same operational lock: a rotation will not trigger during an active benchmark, and vice versa.
When at least one automatic rotation pool is active, the classic automatic cycle in Settings → Measure is paused: the toggle is disabled in the UI, manual benchmarks remain available, and pool rotations become the primary scheduler. This pause persists across container restarts: Companion detects active pools at startup and will not re-enable the benchmark cycle even if auto_benchmark=1 remained in the database.
Pool rotations are visible on the dashboard / and in /history. A switch appears as pool activity; if Measure after switch is enabled, the proxy_qc test also gets the pool badge.
| Type | Severity | Content |
|---|---|---|
| 🟡 Pool rotation | Medium | Pool name, trigger (auto/manual), previous → new server, speed if post-switch measurement is enabled, public IP |
The final selection score now integrates four reliability components, all scaled by the Speed vs stability slider (Settings):
score = (w_cur × current_dl + w_hist × exp_history)
× confidence_factor
× effective_stability
effective_stability = 1 − (stability_weight/100) × (1 − raw_stability)
raw_stability = jitter_factor × loss_factor × reconnect_factor
| Component | Source | Max penalty |
|---|---|---|
| Jitter | Measured each test (jitter_ms) | −15 % at 150 ms |
| Packet loss | Measured each test (packet_loss_pct) | −25 % at 10 % loss |
| Involuntary reconnects | Docker events over 30 d (test_trigger=docker_event) | −10 % per reconnect, max −30 % |
| Confidence (historical variance) | Coefficient of variation over all tests in the scoring window (proxy_qc excluded) | −15 % (LOW) · −5 % (MEDIUM) |
Speed vs stability slider (Settings → Decide):
- 0 — speed only, all stability penalties disabled
- 30 (default) — 30 % of the max penalties applied
- 100 — full penalties — a 300 Mbps server with 3 involuntary reconnects + high jitter can lose up to ~40 % of its score
A 200 Mbps server with no reconnects and stable jitter will be preferred over a 300 Mbps server that disconnects every hour, as soon as
stability_weight ≥ ~20.
Accessible from History → Hourly patterns, this view shows average performance by hour of day (0h–23h) for a selected server.
- Bar chart color-coded by performance relative to the server's best hour: 🟢 ≥ 85 % · 🟡 65–85 % · 🟠 45–65 % · 🔴 < 45 %
- Hours displayed in local time (respects the
TZenvironment variable) - Best and worst hour shown in stat cards
- Quick checks (
proxy_qc) excluded - Visualisation only — this view does not influence the scheduler. The Time optimization setting in Parameters is what uses this data to shift automatic benchmarks.
- Useful for checking whether a specific VPN server shows meaningful performance variation by hour of day
Disabled by default, AirVPN users only. Enable in Settings → Notifications.
How it works:
- Every 24 h, Companion fetches the server list from
airvpn.org/api/status/ - It identifies which countries your configured (name-type) servers belong to
- Any new server that appears in one of those countries is stored in the database for 7 days
UI surfaces:
-
Badge
+Non the Add AirVPN servers button (Servers page) - Dismissable banner at the top of the Servers page: "3 new servers available in your countries (NL, FR)" with a link to the modal
- Changes tab in the add modal: New servers detected section with ⭐ New badge and checkbox for direct one-click add; unified search filter
Discord/Apprise notification: Sent only when new servers are discovered, grouped by country. Uses the global Discord mention field (see Contextual notifications).
After 7 days, servers leave the "new" list automatically. Servers you add to your list no longer appear in the badge/banner.
Companion sends targeted alerts via Discord webhook and/or Apprise based on events. Each alert type can be toggled independently in Settings → Notifications.
| Alert type | Severity | On by default | Trigger |
|---|---|---|---|
| 🔴 VPN outage / emergency failover | Critical | ✅ | Gluetun remains unavailable after the grace period; reports the recovery attempt result |
| 🔴 Server auto-exclude | Critical | ✅ | A server is disabled after N consecutive failures |
| 🔴 Benchmark with no results | Critical | ✅ | A full cycle completes with no valid results |
| 🟡 Automatic switch | Medium | ✅ | Companion switches to a faster server |
| 🟡 New AirVPN servers | Medium | (depends on AirVPN detection) | New servers detected in your countries |
| 🔵 Manual switch | Info | ❌ | Switch triggered manually from the UI |
| 🔵 Benchmark started | Info | ❌ | Confirmed cycle; may announce temporary VPN interruptions and paused containers |
| 🔵 Benchmark complete | Info | ❌ | Benchmark cycle finished successfully |
| 🔵 Already on best | Info | ❌ | Active server is already the best — no change |
| 🔵 Quick check result | Info | ✅ | Manual quick benchmark completed (server, speed, delta vs baseline) |
| 🔵 Catalogue changes | Info | ❌ | Servers added or removed during a catalogue refresh (per-provider detail) |
| 🔵 Optimal window changed | Info | ❌ | The global optimal benchmark hour has changed (based on historical patterns) |
Global Discord mention: a single Discord mention field (e.g. <@123456789> for a user, <@&987654321> for a role) applies to all alerts. A severity threshold is configurable:
- Critical only (default) — mention only for 🔴 alerts
- Medium and critical — mention for 🔴 and 🟡
- All — mention for all alerts
The mention is injected into the Discord payload via
allowed_mentionsto guarantee delivery even on servers with mention restrictions.
Every test automatically measures the stability of the VPN connection, in addition to throughput.
Measurement method:
- Proxy mode — 21 TTFB (Time To First Byte) probes spread across 3 targets (Cloudflare, Google, Quad9). Variance of response times yields jitter; failed requests yield the loss rate.
-
Sidecar mode — the sidecar container's
/pingendpoint performs TCP handshakes to the same 3 targets (20 attempts each). Falls back to None gracefully if the sidecar version doesn't support/ping.
Metrics produced:
-
jitter_ms— standard deviation of response times (ms) — represents variability/instability -
packet_loss_pct— percentage of lost requests/packets -
ping_min_ms/ping_max_ms— best and worst response times
UI surfaces:
- Servers page — Stability column: colored dot 🟢 (jitter < 15 ms, loss < 1 %) / 🟡 (< 50 ms, < 5 %) / 🔴 (above), tooltip with detailed values
- History — Jitter and Loss columns with the same color coding per row
- Hourly patterns — each bar's tooltip includes the average jitter for that hour
Integration into selection score: The score is multiplied by a cumulative penalty factor:
- Jitter:
max(0.85, 1 − jitter_ms / 1000)→ up to −15 % penalty - Loss:
max(0.75, 1 − packet_loss_pct / 40)→ up to −25 % penalty
A fast but unstable server will be ranked below a slightly slower but consistent one.
The GET /metrics endpoint exposes key metrics in Prometheus text format, with no external dependencies.
Available metrics (per server):
-
gluetun_companion_server_avg_dl_mbps— average download throughput (full benchmarks only,proxy_qcexcluded) -
gluetun_companion_server_avg_ul_mbps— average upload throughput -
gluetun_companion_server_avg_latency_ms— average latency -
gluetun_companion_server_test_count— total number of tests -
gluetun_companion_server_failure_count— number of failed tests -
gluetun_companion_server_consecutive_failures— current consecutive failures -
gluetun_companion_server_enabled— 1 if enabled for benchmarking -
gluetun_companion_server_active— 1 if this is the currently active Gluetun server -
gluetun_companion_server_last_benchmark_ts_seconds— Unix timestamp of the last recorded test
Server metrics include server, provider and profile labels, so Grafana filters update automatically when you add servers, providers or VPN profiles.
Global metrics:
-
gluetun_companion_switches_total— total number of switches -
gluetun_companion_switches_success_total— successful switches -
gluetun_companion_benchmark_running— 1 if a benchmark is currently running -
gluetun_companion_benchmark_total_servers,gluetun_companion_benchmark_done_servers,gluetun_companion_benchmark_remaining_servers— progress of the current benchmark/observation cycle -
gluetun_companion_continuous_observation_enabled,gluetun_companion_continuous_observation_running— continuous observation state -
gluetun_companion_rotation_pools_total,gluetun_companion_rotation_pools_enabled,gluetun_companion_rotation_pools_auto_enabled— global pool counters -
gluetun_companion_rotation_pool_last_speed_mbps,gluetun_companion_rotation_pool_last_rotation_timestamp_seconds,gluetun_companion_rotation_pool_next_rotation_timestamp_seconds— per-pool metrics with thepoollabel -
gluetun_companion_last_switch_timestamp_seconds— Unix timestamp of the last switch
Authentication: open by default (standard for internal networks). Two ways to protect /metrics with a Bearer token: set the METRICS_TOKEN environment variable, or configure an API token in Settings → Maintenance → REST API (both are supported; METRICS_TOKEN takes precedence).
Prometheus scrape config (add to prometheus.yml):
scrape_configs:
- job_name: gluetun-companion
static_configs:
- targets: ['gluetun-companion:8765']
# If METRICS_TOKEN is set:
# bearer_token: your-secret-tokenThe API is disabled by default. To enable it: Settings → Maintenance → REST API → Generate a new token.
Authentication: all requests must include the header:
Authorization: Bearer <your-token>
Available endpoints:
| Method | URL | Description |
|---|---|---|
GET |
/api/v1/status |
Active server, VPN state, benchmark running, next cycle |
GET |
/api/v1/servers |
Full server list with average speed, jitter, confidence |
GET |
/api/v1/history |
Test history (?limit=50&offset=0&server=Castor) |
GET |
/api/v1/switches |
Switch history (?limit=20) |
POST |
/api/v1/benchmark/trigger |
Trigger a full benchmark (async, HTTP 202) |
POST |
/api/v1/benchmark/trigger-quick |
Trigger a quick proxy test (async, HTTP 202) |
curl examples:
# Status
curl -H "Authorization: Bearer <token>" http://localhost:8765/api/v1/status
# Trigger a benchmark
curl -X POST -H "Authorization: Bearer <token>" http://localhost:8765/api/v1/benchmark/trigger
# Last 10 tests for server Castor
curl -H "Authorization: Bearer <token>" \
"http://localhost:8765/api/v1/history?limit=10&server=Castor"Response codes:
-
200— success (GET) -
202— trigger accepted (POST) -
401— invalid or missing token -
403— API disabled (no token configured) -
409— a benchmark is already running (POST trigger)
POST triggers return immediately — the benchmark runs in the background. Poll
GET /api/v1/statusto track progress (benchmark_running).
In Settings → Measure: the automatic cycle can be disabled via the Enable automatic benchmark cycle toggle. The interval field is then grayed out. Two buttons are always available (dashboard and settings):
-
Quick benchmark — tests only the active server via the Gluetun HTTP proxy; result in seconds, no VPN interruption, result saved in history (
proxy_qcmethod). - Full benchmark — runs a complete cycle immediately, regardless of the automatic cycle setting or the Quick check option. Uses the configured method (sidecar or proxy), shown in parentheses on the button.
Duration estimate: the dashboard displays a
~min–max / serverrange and an estimated total for the selection that will actually be tested, calculated fromwait_secs,duration,samples,retries, the mode (proxy/sidecar), filters, and smart selection. A⚠️ alert appears automatically if the pessimistic total exceeds 30 minutes. The same estimate is recalculated live in Settings → Measure after each change.
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