Init
This commit is contained in:
@@ -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)
|
||||
```
|
||||
Reference in New Issue
Block a user