This commit is contained in:
2025-10-25 20:11:21 +02:00
commit fd37421245
700 changed files with 211892 additions and 0 deletions

View File

@@ -0,0 +1,358 @@
# 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)
```