# Servarr Stack Stack complet et isolé pour la gestion automatisée des médias, entièrement routé via VPN. ## Architecture ```mermaid flowchart TB subgraph Internet PROTON[ProtonVPN LU
WireGuard] end subgraph Gluetun[gluetun - VPN Container] TRANS[Transmission
localhost:9091] PROWLARR[Prowlarr
localhost:9696] RADARR[Radarr
localhost:7878] SONARR[Sonarr
localhost:8989] end subgraph Caddy[Reverse Proxy] CADDY[Caddy + Authelia SSO] end subgraph Storage[/mnt/mediaserver/servarr] TORRENTS[torrents/] MEDIA[media/] end PROTON <--> Gluetun CADDY -->|gluetun:*| Gluetun TRANS --> TORRENTS PROWLARR --> TRANS RADARR --> TRANS SONARR --> TRANS RADARR --> MEDIA SONARR --> MEDIA ``` !!! success "Kill Switch Intégré" Tous les services partagent le namespace réseau de gluetun via `network_mode: service:gluetun`. Si le VPN tombe, **aucun service n'a accès à Internet**. ## Services | Service | Port interne | Fonction | URL | |---------|--------------|----------|-----| | **Gluetun** | 8000 (control) | VPN container (ProtonVPN LU) | - | | **Transmission** | 9091 | Client BitTorrent | [transmission.talloires.tailfd281f.ts.net](https://transmission.talloires.tailfd281f.ts.net) | | **Prowlarr** | 9696 | Gestionnaire d'indexeurs | [prowlarr.talloires.tailfd281f.ts.net](https://prowlarr.talloires.tailfd281f.ts.net) | | **Radarr** | 7878 | Gestion des films | [radarr.talloires.tailfd281f.ts.net](https://radarr.talloires.tailfd281f.ts.net) | | **Sonarr** | 8989 | Gestion des séries | [sonarr.talloires.tailfd281f.ts.net](https://sonarr.talloires.tailfd281f.ts.net) | !!! note "Accès LAN également disponible" - `prowlarr.talloires.local` - `sonarr.talloires.local` - `radarr.talloires.local` - `transmission.talloires.local` → **bloqué** (Tailscale uniquement) ## Structure des données ``` /mnt/mediaserver/servarr/ ├── torrents/ │ ├── incomplete/ # Downloads en cours │ └── complete/ # Downloads terminés └── media/ ├── movies/ # Films (Radarr → Jellyfin) └── tv/ # Séries (Sonarr → Jellyfin) ``` !!! tip "Hardlinks" Tous les services voient `/data/` qui pointe vers `/mnt/mediaserver/servarr/`. Cela permet les **hardlinks** — pas de copie, déplacement instantané. ## Configuration réseau ### network_mode: service:gluetun Tous les services utilisent `network_mode: "service:gluetun"`, ce qui signifie : - Ils partagent le **même namespace réseau** que gluetun - Ils communiquent entre eux via **localhost** - Les ports sont exposés **uniquement par gluetun** - Pas d'accès direct au réseau Docker ```yaml # Exemple de configuration services: gluetun: ports: - "9091:9091" # Transmission - "9696:9696" # Prowlarr - "7878:7878" # Radarr - "8989:8989" # Sonarr environment: - FIREWALL_OUTBOUND_SUBNETS=192.168.0.0/16,100.64.0.0/10 prowlarr: network_mode: "service:gluetun" depends_on: gluetun: condition: service_healthy ``` ### Configuration interne des apps | App | Setting | Valeur | |-----|---------|--------| | **Prowlarr** | Download Client → Transmission | `localhost:9091` | | **Prowlarr** | Apps → Sonarr | `localhost:8989` | | **Prowlarr** | Apps → Radarr | `localhost:7878` | | **Sonarr** | Download Client → Transmission | `localhost:9091` | | **Radarr** | Download Client → Transmission | `localhost:9091` | !!! warning "Important" Ne pas utiliser les noms de containers (`prowlarr`, `sonarr`, etc.) car ils ne sont pas résolvables dans ce mode réseau. ## VPN Configuration ### ProtonVPN WireGuard ```bash # Vérifier l'IP VPN docker exec gluetun wget -qO- https://ipinfo.io/ip # Doit retourner une IP ProtonVPN Luxembourg (5.253.204.x) ``` | Paramètre | Valeur | |-----------|--------| | Provider | ProtonVPN | | Type | WireGuard | | Serveur | Luxembourg (LU#9) | | Peer Port | 51413 (Transmission) | ### Firewall ```yaml environment: # Autorise accès depuis LAN et Tailscale - FIREWALL_OUTBOUND_SUBNETS=192.168.0.0/16,100.64.0.0/10 # Port forwarding pour seeding - FIREWALL_VPN_INPUT_PORTS=51413 ``` ## Caddy / Reverse Proxy Les services sont exposés via Caddy avec Authelia SSO : ```caddyfile prowlarr.talloires.local, prowlarr.talloires.tailfd281f.ts.net { @api path /api/* handle @api { reverse_proxy gluetun:9696 } handle { import authelia reverse_proxy gluetun:9696 } import internal_tls } ``` !!! info "API sans auth" Les endpoints `/api/*` sont accessibles sans Authelia pour permettre la communication inter-apps. ## Vérifications ### VPN actif ```bash docker exec gluetun wget -qO- https://ipinfo.io ``` Doit afficher une IP ProtonVPN (M247/Datacamp), pas ton IP réelle. ### Connectivité interne ```bash # Depuis gluetun, tester tous les services docker exec gluetun sh -c 'wget -qO- http://localhost:9696/ping' # Prowlarr docker exec gluetun sh -c 'wget -qO- http://localhost:8989/ping' # Sonarr docker exec gluetun sh -c 'wget -qO- http://localhost:7878/ping' # Radarr ``` ### Statut des containers ```bash cd ~/lake/servarr && docker compose ps ``` ### Health check gluetun ```bash docker inspect gluetun --format='{{.State.Health.Status}}' # Doit retourner: healthy ``` ## Fichiers | Fichier | Chemin | |---------|--------| | Docker Compose | `~/lake/servarr/docker-compose.yml` | | Environment | `~/lake/servarr/.env` | | Backup | `~/lake/servarr/docker-compose.yml.bak` | | Données | `/mnt/mediaserver/servarr/` | ## Historique - **2026-01-12** : Migration complète — tous les services via VPN (network_mode: service:gluetun) - **2026-01-08** : Déploiement initial avec Gluetun, Transmission, Prowlarr, Radarr, Sonarr