# gluetun-pia-wireguard-rotator Sidecar die op een cron-schema (en bij container-start) de **snelste** PIA WireGuard-region kiest (TCP-latency) via [pia-wg-config](https://github.com/ccarpinteri/pia-wg-config), `wg0.conf` op het gedeelde gluetun-volume schrijft, en een configureerbare lijst containers herstart. ## Vereisten - Gluetun met `VPN_SERVICE_PROVIDER=custom` en `VPN_TYPE=wireguard` - Gedeeld volume met gluetun (bijv. `/var/dockers/m3u-filter-pia:/gluetun` op gluetun, `/config` op de rotator) - Docker socket (voor `docker restart` van gluetun en eventuele sidecar-containers) - Actief PIA-abonnement ## Environment variables ### Required | Variable | Description | |----------|-------------| | `PIA_USER` | PIA-gebruikersnaam | | `PIA_PASS` | PIA-wachtwoord | | `PIA_REGIONS` | CSV (`nl_amsterdam,france,belgium`) of JSON-array (`["nl_amsterdam","france"]`) | Region-codes moeten overeenkomen met `pia-wg-config` (niet de OpenVPN-namen uit Gluetun's ingebouwde PIA-provider). Lijst opvragen: ```bash docker run --rm --entrypoint pia-wg-config bramkel/gluetun-pia-wireguard-rotator:latest --list-regions ``` ### Optional | Variable | Default | Description | |----------|---------|-------------| | `RESTART_CONTAINERS` | — | CSV of JSON-array met **extra** containers om te herstarten na gluetun (sidecars). Voorbeeld: `SabNZBd,qbittorrent,Spotweb` | | `GLUETUN_CONTAINER` | `m3u-filter-vpn` | Gluetun-container; wordt **altijd als eerste** herstart | | `WG_CONFIG_PATH` | `/config/wireguard/wg0.conf` | Pad waar `wg0.conf` wordt geschreven | | `ROTATOR_STATE_PATH` | `/config/rotator-state.json` | Laatste rotatie-metadata | | `ROTATE_CRON` | `0 3 * * *` | 5-veld cron-expressie (minuut uur dag-van-maand maand dag-van-week), in `TZ`. Macros: `@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly` | | `REGION_SELECT` | `fastest` | `fastest` = laagste TCP-latency naar WG-servers in `PIA_REGIONS`; `random` = willekeurig (slaat vorige region over indien mogelijk) | | `LATENCY_PORT` | `1337` | TCP-poort voor latency-probes | | `LATENCY_TIMEOUT_SECONDS` | `2` | Timeout per probe | | `LATENCY_SAMPLES` | `2` | Aantal samples per server-IP (gemiddelde) | | `LATENCY_SWITCH_MARGIN_MS` | `15` | Alleen switchen van regio als de winst ≥ deze marge is (minder churn / token-calls) | | `SERVERLIST_CACHE_PATH` | `/config/cache/pia-serverlist.json` | Disk-cache voor PIA serverlist (gedeeld met `pia-wg-config`) | | `SERVERLIST_CACHE_TTL` | `24h` | Gebruik cache zonder refresh (`Ns`/`Nm`/`Nh`/`Nd` of seconden) | | `SERVERLIST_CACHE_MAX_AGE` | `168h` | Maximale leeftijd; daarna verplicht vernieuwen (stale fallback bij fetch-fout) | | `WG_CONFIG_MAX_AGE` | `7d` | Geen nieuwe token/config zolang regio gelijk blijft en `wg0.conf` jonger is | | `FORCE_ROTATE` | `false` | `true` = altijd nieuwe config + container-restarts, cache-skip negeren | | `RATE_LIMIT_WAIT_SECONDS` | `3600` | Wachttijd bij PIA rate-limit (`429` / `too_many_attempts`) vóór retry | | `TZ` | `Europe/Brussels` | Tijdzone voor scheduling | `ROTATE_CRON` voorbeelden: `0 */6 * * *` (elke 6 uur), `0 3 * * 1-5` (weekdagen 03:00), `@hourly`. Quote de waarde in Compose (`'ROTATE_CRON=0 3 * * *'`) zodat YAML `*` niet speciaal interpreteert. Oude `ROTATE_AT=HH:MM` werkt nog als `ROTATE_CRON` leeg is. ## Output - `wireguard/wg0.conf` op het gedeelde volume — Gluetun leest dit als `/gluetun/wireguard/wg0.conf` en dit **overschrijft** `WIREGUARD_*` environment variables - `rotator-state.json` — laatste gekozen region, latency-resultaten, timestamp en herstartte containers ## Compose-integratie Zie [`docker-compose.example.yml`](docker-compose.example.yml) voor een volledig voorbeeld met `m3u-filter-vpn`, m3u-editor en xtream-proxy. ### Nieuwe service toevoegen ```yaml gluetun-pia-wireguard-rotator: image: bramkel/gluetun-pia-wireguard-rotator:latest container_name: gluetun-pia-wireguard-rotator restart: unless-stopped environment: - TZ=Europe/Brussels - PIA_USER=${PIA_USER} - PIA_PASS=${PIA_PASSWORD} - PIA_REGIONS=nl_amsterdam,france,belgium - GLUETUN_CONTAINER=downloaders-vpn - RESTART_CONTAINERS=SabNZBd,qbittorrent,nzbhydra2,Spotweb - 'ROTATE_CRON=0 3 * * *' # optioneel: REGION_SELECT=random volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - /var/dockers/m3u-filter-pia:/config depends_on: - m3u-filter-vpn ``` Zet `PIA_USER` en `PIA_PASSWORD` in een host-`.env` (niet inline in compose). ### Gluetun opschonen (aanbevolen na eerste succesvolle rotatie) Zodra `wg0.conf` bestaat, heeft het bestand voorrang op env-vars. Verwijder uit `m3u-filter-vpn` om verwarring te voorkomen: - `WIREGUARD_ENDPOINT_IP` - `WIREGUARD_PUBLIC_KEY` - `WIREGUARD_PRIVATE_KEY` - `WIREGUARD_ADDRESSES` Behoud minimaal: ```yaml environment: - VPN_SERVICE_PROVIDER=custom - VPN_TYPE=wireguard ``` Optioneel host-`.env`-keys (`WIREGUARD_*`) opruimen als die niet meer gebruikt worden. ## Deploy 1. Push/build image (`Dockers/gluetun-pia-wireguard-rotator/**` triggert Gitea CI → `bramkel/gluetun-pia-wireguard-rotator:latest`) 2. `docker compose up -d gluetun-pia-wireguard-rotator` 3. Controleer logs: `docker logs gluetun-pia-wireguard-rotator` en `docker logs m3u-filter-vpn` ## Gedrag 1. Bij start / cron: latency meten (of random kiezen) 2. Serverlist komt uit disk-cache (`SERVERLIST_CACHE_*`); token/API alleen bij echte config-refresh 3. Geen `pia-wg-config` + geen restarts als regio gelijk blijft én `wg0.conf` jonger is dan `WG_CONFIG_MAX_AGE` 4. Anders: nieuwe config schrijven, `GLUETUN_CONTAINER` eerst herstarten, daarna `RESTART_CONTAINERS` **Let op:** zet gluetun **niet** in `RESTART_CONTAINERS`; gebruik `GLUETUN_CONTAINER` daarvoor. Sidecars met `network_mode: service:...` horen in `RESTART_CONTAINERS`. **Let op:** elke rotatie veroorzaakt kort downtime voor alle VPN-afhankelijke services. ## Security - De Docker socket geeft de rotator rechten om containers te herstarten; mount read-only waar mogelijk - `wg0.conf` bevat private keys (`chmod 600`) - Bewaar PIA-credentials in `.env`, niet in version control