# Integrating Servarr Stack with Traefik ## Your Current Setup You have a Servarr media automation stack (`servarr.yaml`) with: - **Gluetun** - VPN container (ProtonVPN) - **qBittorrent** - Torrent client - **Sonarr/Radarr/Lidarr** - Media management - **Prowlarr** - Indexer manager - **Bazarr** - Subtitle downloader - **Recyclarr** - Configuration sync - **Dozzle** - Log viewer - **Watchtower** - Auto-updater **Special consideration:** Most services use `network_mode: service:gluetun`, meaning they share gluetun's network namespace for VPN routing. --- ## Challenge: VPN Network Mode Services using `network_mode: service:gluetun` **cannot** directly connect to the `traefik_proxy` network. They're locked into gluetun's network namespace for VPN routing. ### Options for External Access **Option 1: Don't Expose VPN Services Externally (Recommended)** - Keep VPN-routed services local-only - Access via local network or Tailscale/Wireguard - Most secure approach - Expose only Dozzle (log viewer) via Traefik for monitoring **Option 2: Expose Gluetun to Traefik** - Connect gluetun container to Traefik network - Route to services through gluetun's exposed ports - More complex configuration - Potential security considerations **Option 3: Split the Stack** - Keep VPN services in current stack (local-only) - Move non-VPN services (Dozzle) to separate stack for Traefik access --- ## Recommended Approach: Hybrid Setup ### Keep VPN Services Local, Expose Dozzle via Traefik This gives you: - ✅ Secure VPN routing for download/automation apps (local access only) - ✅ External access to Dozzle for log monitoring - ✅ Simple configuration - ✅ No VPN security compromise --- ## Implementation ### Current Directory Structure ``` /mnt/tank/ ├── configs/ │ ├── gluetun/ │ ├── qbittorrent/ │ ├── sonarr/ │ ├── radarr/ │ ├── lidarr/ │ ├── prowlarr/ │ ├── bazarr/ │ ├── recyclarr/ │ └── dozzle/ └── media/ ``` ### Modified servarr.yaml **Keep the current file mostly as-is, but extract Dozzle to a separate stack:** #### Step 1: Deploy Traefik (if not done) See: [[Traefik Multi-Stack Setup#Step 1]] #### Step 2: Split Dozzle to Separate Stack **Remove Dozzle from `servarr.yaml`:** ```yaml # Remove this section from servarr.yaml: dozzle: image: amir20/dozzle:latest container_name: dozzle ports: - 9999:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro restart: unless-stopped ``` **Create `/mnt/tank/stacks/dozzle/docker-compose.yml`:** ```yaml version: '3.8' networks: traefik_proxy: external: true services: dozzle: image: amir20/dozzle:latest container_name: dozzle restart: unless-stopped networks: - traefik_proxy volumes: - /var/run/docker.sock:/var/run/docker.sock:ro environment: - TZ=Europe/Amsterdam labels: - "traefik.enable=true" - "traefik.docker.network=traefik_proxy" - "traefik.http.routers.dozzle.rule=Host(`logs.yourdomain.com`)" - "traefik.http.routers.dozzle.entrypoints=websecure" - "traefik.http.routers.dozzle.tls.certresolver=cloudflare" - "traefik.http.services.dozzle.loadbalancer.server.port=8080" # Optional: Add authentication - "traefik.http.routers.dozzle.middlewares=dozzle-auth" - "traefik.http.middlewares.dozzle-auth.basicauth.users=admin:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/" ``` **Deploy Dozzle:** ```bash mkdir -p /mnt/tank/stacks/dozzle cd /mnt/tank/stacks/dozzle # Create docker-compose.yml with content above, then: docker compose up -d ``` Now accessible at: `https://logs.yourdomain.com` #### Step 3: Keep Servarr Stack As-Is Your VPN-routed services remain accessible on local network: - qBittorrent: `http://truenas-ip:8080` - Sonarr: `http://truenas-ip:8989` - Radarr: `http://truenas-ip:7878` - Prowlarr: `http://truenas-ip:9696` - Lidarr: `http://truenas-ip:8686` - Bazarr: `http://truenas-ip:6767` **Access these via:** - Local network (current method) - VPN (Tailscale/Wireguard) for remote access - SSH tunnel for secure remote access --- ## Alternative: Expose Select Services via Traefik If you want some *arr services accessible externally (e.g., Sonarr/Radarr for mobile apps): ### Option: Duplicate Ports in Gluetun Add gluetun to Traefik network and route through it: **Modified servarr.yaml:** ```yaml services: gluetun: image: qmcgaw/gluetun:latest container_name: gluetun cap_add: - NET_ADMIN environment: - VPN_SERVICE_PROVIDER=protonvpn - VPN_TYPE=wireguard - WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY} - SERVER_COUNTRIES=Netherlands - TZ=Europe/Amsterdam volumes: - /mnt/tank/configs/gluetun:/gluetun - /mnt/tank/configs/gluetun-tmp:/tmp/gluetun ports: - 8080:8080 # qBittorrent - 7878:7878 # Radarr - 8686:8686 # Lidarr - 8989:8989 # Sonarr - 9696:9696 # Prowlarr - 6767:6767 # Bazarr networks: - traefik_proxy # Add this restart: unless-stopped labels: # Sonarr via Traefik - "traefik.enable=true" - "traefik.docker.network=traefik_proxy" - "traefik.http.routers.sonarr.rule=Host(`sonarr.yourdomain.com`)" - "traefik.http.routers.sonarr.entrypoints=websecure" - "traefik.http.routers.sonarr.tls.certresolver=cloudflare" - "traefik.http.routers.sonarr.service=sonarr" - "traefik.http.services.sonarr.loadbalancer.server.port=8989" # Radarr via Traefik - "traefik.http.routers.radarr.rule=Host(`radarr.yourdomain.com`)" - "traefik.http.routers.radarr.entrypoints=websecure" - "traefik.http.routers.radarr.tls.certresolver=cloudflare" - "traefik.http.routers.radarr.service=radarr" - "traefik.http.services.radarr.loadbalancer.server.port=7878" # Add more services as needed... networks: traefik_proxy: external: true # ... rest of services remain the same ``` **Security Note:** This exposes your download apps to the internet. Consider: - Strong authentication in each app - Traefik basic auth middleware - Firewall rules limiting access to your IP - Or stick with VPN-only access --- ## Recommended Final Architecture ``` Internet (Port 80/443) ↓ Traefik ├── Gitea (https://git.yourdomain.com) ├── Dozzle (https://logs.yourdomain.com) └── [Future Services] Local Network Only: ↓ Servarr Stack (VPN-routed) ├── Sonarr (http://truenas-ip:8989) ├── Radarr (http://truenas-ip:7878) ├── qBittorrent (http://truenas-ip:8080) └── [Other *arr apps] ``` **Access Servarr remotely via:** - Tailscale/Wireguard VPN - SSH tunnel: `ssh -L 8989:localhost:8989 user@truenas-ip` --- ## Stack Management ### Servarr Stack ```bash # Start/stop Servarr stack cd /mnt/tank/stacks/servarr docker compose up -d docker compose down # Update containers (Watchtower handles this automatically) docker compose pull docker compose up -d ``` ### Dozzle (Traefik-routed) ```bash cd /mnt/tank/stacks/dozzle docker compose up -d docker compose down ``` ### Gitea (Traefik-routed) ```bash cd /mnt/tank/stacks/gitea docker compose up -d docker compose down ``` All stacks are independent! --- ## DNS Records for Cloudflare Add A records: | Name | Target | Proxy | |------|--------|-------| | git | Your-Public-IP | DNS only | | logs | Your-Public-IP | DNS only | | traefik | Your-Public-IP | DNS only | --- ## Environment Variables Create `.env` file in servarr directory for sensitive data: ```bash # /mnt/tank/stacks/servarr/.env WIREGUARD_PRIVATE_KEY=your-wireguard-key ``` Reference in docker-compose: ```yaml environment: - WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY} ``` --- ## Security Best Practices 1. **Don't expose VPN-routed services directly to internet** - Use Tailscale/Wireguard for remote access - Or use SSH tunnels 2. **Enable authentication on all services** - Each *arr app has built-in auth - Configure strong passwords 3. **Use Traefik middlewares for additional security** - Basic auth - IP whitelisting - Rate limiting 4. **Keep Watchtower for auto-updates** - Already configured in your stack - Keeps containers patched --- ## Next Steps - [ ] Deploy Traefik (if not already done) - [ ] Move Dozzle to separate stack with Traefik labels - [ ] Deploy Dozzle with external access - [ ] Keep Servarr services local-only (current setup) - [ ] Set up Tailscale/Wireguard for secure remote access to Servarr - [ ] Add DNS records for exposed services - [ ] Test accessing Dozzle externally - [ ] Configure authentication for all services --- ## Additional Notes Your directory structure: ``` /mnt/tank/stacks/ ├── traefik/ ├── gitea/ ├── servarr/ (your existing stack) └── dozzle/ (optional split from servarr) ```