Initial template repository
🎬 ARR Suite Template Bootstrap - Complete Media Automation Stack Features: - 16 production services (Prowlarr, Sonarr, Radarr, Plex, etc.) - One-command Ansible deployment - VPN-protected downloads via Gluetun - Tailscale secure access - Production-ready security (UFW, Fail2Ban) - Automated backups and monitoring - Comprehensive documentation Ready for customization and deployment to any VPS. Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
421
docs/CONFIGURATION.md
Normal file
421
docs/CONFIGURATION.md
Normal file
@@ -0,0 +1,421 @@
|
||||
# Configuration Guide
|
||||
|
||||
This guide covers the initial configuration of each application in the Arrs stack after deployment.
|
||||
|
||||
## Initial Setup Workflow
|
||||
|
||||
1. **Start with Prowlarr** - Set up indexers first
|
||||
2. **Configure Sonarr/Radarr/Lidarr** - Set up media management
|
||||
3. **Set up Bazarr** - Configure subtitle management
|
||||
4. **Add Download Clients** - Connect to your torrent/usenet clients
|
||||
|
||||
## Prowlarr Configuration
|
||||
|
||||
Prowlarr acts as the central indexer manager for all other applications.
|
||||
|
||||
### First-Time Setup
|
||||
|
||||
1. Access Prowlarr at `http://YOUR_NAS_IP:9696`
|
||||
2. Complete the initial setup wizard
|
||||
3. Set authentication if desired (Settings → General → Security)
|
||||
|
||||
### Adding Indexers
|
||||
|
||||
1. Go to **Indexers** → **Add Indexer**
|
||||
2. Choose your indexer type (Public or Private)
|
||||
3. Configure indexer settings:
|
||||
- **Name**: Descriptive name
|
||||
- **URL**: Indexer URL
|
||||
- **API Key**: If required
|
||||
- **Categories**: Select relevant categories
|
||||
4. Test the connection
|
||||
5. Save the indexer
|
||||
|
||||
### Connecting to Apps
|
||||
|
||||
1. Go to **Settings** → **Apps**
|
||||
2. Click **Add Application**
|
||||
3. Select the application type (Sonarr, Radarr, etc.)
|
||||
4. Configure connection:
|
||||
- **Name**: Application name
|
||||
- **Server**: `172.20.0.1` (synobridge gateway)
|
||||
- **Port**: Application port (8989 for Sonarr, 7878 for Radarr, etc.)
|
||||
- **API Key**: Get from the target application
|
||||
5. Test and save
|
||||
|
||||
## Sonarr Configuration (TV Shows)
|
||||
|
||||
### Initial Setup
|
||||
|
||||
1. Access Sonarr at `http://YOUR_NAS_IP:8989`
|
||||
2. Complete the setup wizard
|
||||
3. Set authentication (Settings → General → Security)
|
||||
|
||||
### Root Folders
|
||||
|
||||
1. Go to **Settings** → **Media Management**
|
||||
2. Click **Add Root Folder**
|
||||
3. Set path: `/data/media/tv`
|
||||
4. Save the configuration
|
||||
|
||||
### Quality Profiles
|
||||
|
||||
1. Go to **Settings** → **Profiles** → **Quality Profiles**
|
||||
2. Edit or create profiles based on your preferences:
|
||||
- **HD-1080p**: For 1080p content
|
||||
- **HD-720p/1080p**: For mixed HD content
|
||||
- **Any**: For any quality
|
||||
|
||||
### Download Clients
|
||||
|
||||
1. Go to **Settings** → **Download Clients**
|
||||
2. Click **Add Download Client**
|
||||
3. Select your client type (qBittorrent, Transmission, etc.)
|
||||
4. Configure connection:
|
||||
- **Host**: `172.20.0.1`
|
||||
- **Port**: Your client's port
|
||||
- **Username/Password**: If required
|
||||
- **Category**: `tv` (recommended)
|
||||
5. Test and save
|
||||
|
||||
### Indexers (if not using Prowlarr)
|
||||
|
||||
1. Go to **Settings** → **Indexers**
|
||||
2. Add indexers manually or sync from Prowlarr
|
||||
|
||||
## Radarr Configuration (Movies)
|
||||
|
||||
### Initial Setup
|
||||
|
||||
1. Access Radarr at `http://YOUR_NAS_IP:7878`
|
||||
2. Complete the setup wizard
|
||||
3. Set authentication (Settings → General → Security)
|
||||
|
||||
### Root Folders
|
||||
|
||||
1. Go to **Settings** → **Media Management**
|
||||
2. Click **Add Root Folder**
|
||||
3. Set path: `/data/media/movies`
|
||||
4. Save the configuration
|
||||
|
||||
### Quality Profiles
|
||||
|
||||
Configure quality profiles similar to Sonarr:
|
||||
- **HD-1080p**
|
||||
- **HD-720p/1080p**
|
||||
- **Ultra-HD** (for 4K content)
|
||||
|
||||
### Download Clients
|
||||
|
||||
1. Go to **Settings** → **Download Clients**
|
||||
2. Configure similar to Sonarr
|
||||
3. Set **Category**: `movies`
|
||||
|
||||
## Lidarr Configuration (Music)
|
||||
|
||||
### Initial Setup
|
||||
|
||||
1. Access Lidarr at `http://YOUR_NAS_IP:8686`
|
||||
2. Complete the setup wizard
|
||||
3. Set authentication (Settings → General → Security)
|
||||
|
||||
### Root Folders
|
||||
|
||||
1. Go to **Settings** → **Media Management**
|
||||
2. Click **Add Root Folder**
|
||||
3. Set path: `/data/media/music`
|
||||
4. Save the configuration
|
||||
|
||||
### Quality Profiles
|
||||
|
||||
Configure for music quality:
|
||||
- **Lossless**: FLAC, ALAC
|
||||
- **High Quality**: 320kbps MP3
|
||||
- **Standard**: 192-256kbps MP3
|
||||
|
||||
### Download Clients
|
||||
|
||||
1. Configure similar to other apps
|
||||
2. Set **Category**: `music`
|
||||
|
||||
### Metadata Profiles
|
||||
|
||||
1. Go to **Settings** → **Profiles** → **Metadata Profiles**
|
||||
2. Configure which metadata to download:
|
||||
- **Primary Types**: Album, Single, EP
|
||||
- **Secondary Types**: Studio, Live, etc.
|
||||
|
||||
## Bazarr Configuration (Subtitles)
|
||||
|
||||
### Initial Setup
|
||||
|
||||
1. Access Bazarr at `http://YOUR_NAS_IP:6767`
|
||||
2. Complete the setup wizard
|
||||
3. Set authentication (Settings → General → Security)
|
||||
|
||||
### Sonarr Integration
|
||||
|
||||
1. Go to **Settings** → **Sonarr**
|
||||
2. Enable Sonarr integration
|
||||
3. Configure connection:
|
||||
- **Address**: `172.20.0.1`
|
||||
- **Port**: `8989`
|
||||
- **API Key**: From Sonarr
|
||||
- **Base URL**: Leave empty
|
||||
4. Set **Path Mappings** if needed
|
||||
5. Test and save
|
||||
|
||||
### Radarr Integration
|
||||
|
||||
1. Go to **Settings** → **Radarr**
|
||||
2. Configure similar to Sonarr integration
|
||||
3. Use port `7878` for Radarr
|
||||
|
||||
### Subtitle Providers
|
||||
|
||||
1. Go to **Settings** → **Providers**
|
||||
2. Add subtitle providers:
|
||||
- **OpenSubtitles**: Free, requires registration
|
||||
- **Subscene**: Free, no registration
|
||||
- **Addic7ed**: Free, requires registration
|
||||
3. Configure provider settings and authentication
|
||||
|
||||
### Languages
|
||||
|
||||
1. Go to **Settings** → **Languages**
|
||||
2. Add desired subtitle languages
|
||||
3. Set language priorities
|
||||
|
||||
## Download Client Configuration
|
||||
|
||||
### qBittorrent Example
|
||||
|
||||
If using qBittorrent as your download client:
|
||||
|
||||
1. **Connection Settings**:
|
||||
- Host: `172.20.0.1`
|
||||
- Port: `8081` (qBittorrent WebUI port - configured to avoid conflict with SABnzbd)
|
||||
- Username/Password: Your qBittorrent credentials
|
||||
|
||||
2. **Category Setup** in qBittorrent:
|
||||
- `movies` → `/data/torrents/movies`
|
||||
- `tv` → `/data/torrents/tv`
|
||||
- `music` → `/data/torrents/music`
|
||||
|
||||
3. **Path Mappings** (if needed):
|
||||
- Remote Path: `/downloads`
|
||||
- Local Path: `/data/torrents`
|
||||
|
||||
### Transmission Example
|
||||
|
||||
For Transmission:
|
||||
|
||||
1. **Connection Settings**:
|
||||
- Host: `172.20.0.1`
|
||||
- Port: `9091` (default Transmission port)
|
||||
- Username/Password: If authentication enabled
|
||||
|
||||
2. **Directory Setup**:
|
||||
- Download Directory: `/data/torrents`
|
||||
- Use categories or labels for organization
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Custom Scripts
|
||||
|
||||
You can add custom scripts for post-processing:
|
||||
|
||||
1. Go to **Settings** → **Connect**
|
||||
2. Add **Custom Script** connection
|
||||
3. Configure script path and triggers
|
||||
|
||||
### Notifications
|
||||
|
||||
Set up notifications for downloads and imports:
|
||||
|
||||
1. Go to **Settings** → **Connect**
|
||||
2. Add notification services:
|
||||
- **Discord**
|
||||
- **Slack**
|
||||
- **Email**
|
||||
- **Pushover**
|
||||
|
||||
### Quality Definitions
|
||||
|
||||
Fine-tune quality definitions:
|
||||
|
||||
1. Go to **Settings** → **Quality**
|
||||
2. Adjust size limits for each quality
|
||||
3. Set preferred quality ranges
|
||||
|
||||
## Remote Path Mappings
|
||||
|
||||
If your download client is on a different system or uses different paths:
|
||||
|
||||
1. Go to **Settings** → **Download Clients**
|
||||
2. Click **Add Remote Path Mapping**
|
||||
3. Configure:
|
||||
- **Host**: Download client IP
|
||||
- **Remote Path**: Path as seen by download client
|
||||
- **Local Path**: Path as seen by Arr application
|
||||
|
||||
## Backup Configuration
|
||||
|
||||
### Export Settings
|
||||
|
||||
Each application allows exporting settings:
|
||||
|
||||
1. Go to **System** → **Backup**
|
||||
2. Click **Backup Now**
|
||||
3. Download the backup file
|
||||
|
||||
### Automated Backups
|
||||
|
||||
Use the provided backup script:
|
||||
|
||||
```bash
|
||||
# Create backup
|
||||
./scripts/backup.sh
|
||||
|
||||
# Schedule with cron (optional)
|
||||
crontab -e
|
||||
# Add: 0 2 * * 0 /path/to/synology-arrs-stack/scripts/backup.sh
|
||||
```
|
||||
|
||||
## Monitoring and Maintenance
|
||||
|
||||
### Health Checks
|
||||
|
||||
Monitor application health:
|
||||
|
||||
1. Check **System** → **Status** in each app
|
||||
2. Review **System** → **Logs** for errors
|
||||
3. Use the logs script: `./scripts/logs.sh status`
|
||||
|
||||
### Updates
|
||||
|
||||
Keep applications updated:
|
||||
|
||||
1. **Manual**: Pull new images and restart containers
|
||||
2. **Automated**: Use Watchtower or similar tools
|
||||
3. **Script**: Use `./scripts/deploy.sh` to update
|
||||
|
||||
### Performance Tuning
|
||||
|
||||
Optimize performance:
|
||||
|
||||
1. **Resource Limits**: Set CPU/memory limits in docker-compose
|
||||
2. **Database Maintenance**: Regular database cleanup
|
||||
3. **Log Rotation**: Configure log rotation to save space
|
||||
|
||||
## Troubleshooting Common Issues
|
||||
|
||||
### Import Issues
|
||||
|
||||
1. **Check file permissions**: Ensure dockerlimited user can access files
|
||||
2. **Verify paths**: Confirm download and media paths are correct
|
||||
3. **Review logs**: Check application logs for specific errors
|
||||
|
||||
### Connection Issues
|
||||
|
||||
1. **Network connectivity**: Test connections between services
|
||||
2. **API keys**: Verify API keys are correct and active
|
||||
3. **Firewall**: Ensure ports are open
|
||||
|
||||
### Performance Issues
|
||||
|
||||
1. **Resource usage**: Monitor CPU and memory usage
|
||||
2. **Disk I/O**: Check for disk bottlenecks
|
||||
3. **Network**: Verify network performance
|
||||
|
||||
For more detailed troubleshooting, see [TROUBLESHOOTING.md](TROUBLESHOOTING.md).
|
||||
|
||||
## New Services Configuration
|
||||
|
||||
### Whisparr Configuration (Adult Content)
|
||||
|
||||
Whisparr manages adult content similar to Sonarr/Radarr.
|
||||
|
||||
1. Access Whisparr at `http://YOUR_VPS_IP:6969`
|
||||
2. **Media Management**:
|
||||
- Root Folder: `/data/xxx`
|
||||
- File naming and organization similar to Sonarr
|
||||
3. **Indexers**: Connect via Prowlarr or add manually
|
||||
4. **Download Clients**: Use same clients as other Arrs
|
||||
5. **Quality Profiles**: Set up quality preferences for adult content
|
||||
|
||||
### Tautulli Configuration (Plex Monitoring)
|
||||
|
||||
Tautulli provides detailed statistics and monitoring for Plex.
|
||||
|
||||
1. Access Tautulli at `http://YOUR_VPS_IP:8181`
|
||||
2. **Initial Setup**:
|
||||
- Plex Server: `http://plex:32400` (internal Docker network)
|
||||
- Plex Token: Get from Plex settings
|
||||
3. **Configuration**:
|
||||
- Enable activity monitoring
|
||||
- Set up notification agents
|
||||
- Configure user management
|
||||
4. **Features**:
|
||||
- View play statistics
|
||||
- Monitor user activity
|
||||
- Set up kill stream notifications
|
||||
- Generate usage reports
|
||||
|
||||
### Jellyseerr Configuration (Media Requests)
|
||||
|
||||
Jellyseerr allows users to request media additions.
|
||||
|
||||
1. Access Jellyseerr at `http://YOUR_VPS_IP:5055`
|
||||
2. **Initial Setup**:
|
||||
- Connect to Plex server: `http://plex:32400`
|
||||
- Import Plex libraries and users
|
||||
3. **Service Connections**:
|
||||
- **Sonarr**: `http://sonarr:8989` with API key
|
||||
- **Radarr**: `http://radarr:7878` with API key
|
||||
- **Whisparr**: `http://whisparr:6969` with API key (if desired)
|
||||
4. **User Management**:
|
||||
- Set user permissions and quotas
|
||||
- Configure approval workflows
|
||||
- Set up notification preferences
|
||||
|
||||
### TubeArchivist Configuration (YouTube Archiving)
|
||||
|
||||
TubeArchivist downloads and organizes YouTube content.
|
||||
|
||||
1. Access TubeArchivist at `http://YOUR_VPS_IP:8000`
|
||||
2. **Initial Setup**:
|
||||
- Username: `tubearchivist`
|
||||
- Password: `verysecret` (change after first login)
|
||||
3. **Configuration**:
|
||||
- **Downloads**: Set quality preferences and formats
|
||||
- **Channels**: Subscribe to channels for automatic downloads
|
||||
- **Playlists**: Import and monitor playlists
|
||||
- **Scheduling**: Set up download schedules
|
||||
4. **Integration**:
|
||||
- Media files stored in `/data/youtube`
|
||||
- Can be added to Plex as a library if desired
|
||||
- Elasticsearch provides search functionality
|
||||
- Redis handles task queuing
|
||||
|
||||
#### TubeArchivist Dependencies
|
||||
|
||||
- **Elasticsearch**: Provides search and indexing (internal port 9200)
|
||||
- **Redis**: Handles background tasks and caching (internal port 6379)
|
||||
- Both services are automatically configured and don't require manual setup
|
||||
|
||||
### Security Considerations for New Services
|
||||
|
||||
1. **Change Default Passwords**:
|
||||
- TubeArchivist: Change from `verysecret`
|
||||
- Elasticsearch: Change from `verysecret`
|
||||
|
||||
2. **Access Control**:
|
||||
- Consider using reverse proxy with authentication
|
||||
- Limit access via UFW firewall rules
|
||||
- Use Tailscale for secure remote access
|
||||
|
||||
3. **Resource Usage**:
|
||||
- TubeArchivist with Elasticsearch can be resource-intensive
|
||||
- Monitor disk usage for YouTube downloads
|
||||
- Consider setting download limits and cleanup policies
|
||||
205
docs/SERVICE_ACCESS.md
Normal file
205
docs/SERVICE_ACCESS.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# 🌐 Service Access Guide
|
||||
|
||||
This guide provides direct access URLs for all services in your Arrs media stack deployment.
|
||||
|
||||
## 🔗 **Tailscale Access (Recommended)**
|
||||
|
||||
**Tailscale IP**: `YOUR_TAILSCALE_IP`
|
||||
|
||||
All services are accessible via your Tailscale network for secure remote access:
|
||||
|
||||
### 📺 **Core Media Management (The Arrs)**
|
||||
|
||||
| Service | URL | Purpose | Default Login |
|
||||
|---------|-----|---------|---------------|
|
||||
| **Sonarr** | http://YOUR_TAILSCALE_IP:8989 | TV show management & automation | No default login |
|
||||
| **Radarr** | http://YOUR_TAILSCALE_IP:7878 | Movie management & automation | No default login |
|
||||
| **Lidarr** | http://YOUR_TAILSCALE_IP:8686 | Music management & automation | No default login |
|
||||
| **Bazarr** | http://YOUR_TAILSCALE_IP:6767 | Subtitle management & automation | No default login |
|
||||
| **Prowlarr** | http://YOUR_TAILSCALE_IP:9696 | Indexer management & search | No default login |
|
||||
| **Whisparr** | http://YOUR_TAILSCALE_IP:6969 | Adult content management | No default login |
|
||||
|
||||
### ⬇️ **Download Clients (VPN Protected)**
|
||||
|
||||
| Service | URL | Purpose | Default Login |
|
||||
|---------|-----|---------|---------------|
|
||||
| **SABnzbd** | http://YOUR_TAILSCALE_IP:8080 | Usenet downloader (via VPN) | Setup wizard on first run |
|
||||
| **qBittorrent** | http://YOUR_TAILSCALE_IP:8081 | BitTorrent client (via VPN) | admin / adminadmin |
|
||||
|
||||
**⚠️ Important**: Change qBittorrent default password immediately after first login!
|
||||
|
||||
### 🎬 **Media Server & Management**
|
||||
|
||||
| Service | URL | Purpose | Default Login |
|
||||
|---------|-----|---------|---------------|
|
||||
| **Plex** | http://YOUR_TAILSCALE_IP:32400/web | Media streaming server | Plex account required |
|
||||
| **Tautulli** | http://YOUR_TAILSCALE_IP:8181 | Plex monitoring & statistics | No default login |
|
||||
| **Jellyseerr** | http://YOUR_TAILSCALE_IP:5055 | Media request management | Setup wizard on first visit |
|
||||
|
||||
### 📺 **YouTube Archiving**
|
||||
|
||||
| Service | URL | Purpose | Default Login |
|
||||
|---------|-----|---------|---------------|
|
||||
| **TubeArchivist** | http://YOUR_TAILSCALE_IP:8000 | YouTube content archiving | Setup wizard on first visit |
|
||||
|
||||
## 🌍 **Public Internet Access**
|
||||
|
||||
If you've enabled public access in your configuration, services are also accessible via your VPS public IP:
|
||||
|
||||
### 📺 **Core Media Management**
|
||||
- **Sonarr**: `http://YOUR_VPS_IP:8989`
|
||||
- **Radarr**: `http://YOUR_VPS_IP:7878`
|
||||
- **Lidarr**: `http://YOUR_VPS_IP:8686`
|
||||
- **Bazarr**: `http://YOUR_VPS_IP:6767`
|
||||
- **Prowlarr**: `http://YOUR_VPS_IP:9696`
|
||||
- **Whisparr**: `http://YOUR_VPS_IP:6969`
|
||||
|
||||
### ⬇️ **Download Clients**
|
||||
- **SABnzbd**: `http://YOUR_VPS_IP:8080`
|
||||
- **qBittorrent**: `http://YOUR_VPS_IP:8081`
|
||||
|
||||
### 🎬 **Media Server & Management**
|
||||
- **Plex**: `http://YOUR_VPS_IP:32400/web`
|
||||
- **Tautulli**: `http://YOUR_VPS_IP:8181`
|
||||
- **Jellyseerr**: `http://YOUR_VPS_IP:5055`
|
||||
|
||||
### 📺 **YouTube Archiving**
|
||||
- **TubeArchivist**: `http://YOUR_VPS_IP:8000`
|
||||
|
||||
## 🔐 **Security Recommendations**
|
||||
|
||||
### 🛡️ **Tailscale Access (Recommended)**
|
||||
- **✅ Secure**: All traffic encrypted through Tailscale VPN
|
||||
- **✅ Private**: Services not exposed to public internet
|
||||
- **✅ Convenient**: Access from any device with Tailscale installed
|
||||
- **✅ No port forwarding**: No need to open firewall ports
|
||||
|
||||
### 🌐 **Public Access Considerations**
|
||||
- **⚠️ Security Risk**: Services exposed to public internet
|
||||
- **🔒 Authentication**: Ensure strong passwords on all services
|
||||
- **🛡️ Firewall**: UFW firewall provides basic protection
|
||||
- **📊 Monitoring**: Fail2ban monitors for intrusion attempts
|
||||
|
||||
## 🚀 **Quick Access Bookmarks**
|
||||
|
||||
Save these bookmarks for easy access to your media stack:
|
||||
|
||||
### 📱 **Mobile/Tablet Bookmarks**
|
||||
```
|
||||
Sonarr TV: http://YOUR_TAILSCALE_IP:8989
|
||||
Radarr Movies: http://YOUR_TAILSCALE_IP:7878
|
||||
Plex Media: http://YOUR_TAILSCALE_IP:32400/web
|
||||
Jellyseerr Requests: http://YOUR_TAILSCALE_IP:5055
|
||||
```
|
||||
|
||||
### 💻 **Desktop Bookmarks**
|
||||
```
|
||||
Media Management Dashboard:
|
||||
├── Sonarr (TV): http://YOUR_TAILSCALE_IP:8989
|
||||
├── Radarr (Movies): http://YOUR_TAILSCALE_IP:7878
|
||||
├── Lidarr (Music): http://YOUR_TAILSCALE_IP:8686
|
||||
├── Bazarr (Subtitles): http://YOUR_TAILSCALE_IP:6767
|
||||
├── Prowlarr (Indexers): http://YOUR_TAILSCALE_IP:9696
|
||||
└── Whisparr (Adult): http://YOUR_TAILSCALE_IP:6969
|
||||
|
||||
Download Clients:
|
||||
├── SABnzbd: http://YOUR_TAILSCALE_IP:8080
|
||||
└── qBittorrent: http://YOUR_TAILSCALE_IP:8081
|
||||
|
||||
Media & Monitoring:
|
||||
├── Plex Server: http://YOUR_TAILSCALE_IP:32400/web
|
||||
├── Tautulli Stats: http://YOUR_TAILSCALE_IP:8181
|
||||
├── Jellyseerr Requests: http://YOUR_TAILSCALE_IP:5055
|
||||
└── TubeArchivist: http://YOUR_TAILSCALE_IP:8000
|
||||
```
|
||||
|
||||
## 🔧 **Service Configuration Tips**
|
||||
|
||||
### 🎯 **First-Time Setup Priority**
|
||||
1. **Prowlarr** (http://YOUR_TAILSCALE_IP:9696) - Configure indexers first
|
||||
2. **Sonarr/Radarr/Lidarr** - Add Prowlarr as indexer source
|
||||
3. **Download Clients** - Configure qBittorrent/SABnzbd in Arrs
|
||||
4. **Plex** - Add media libraries and configure remote access
|
||||
5. **Jellyseerr** - Connect to Plex and configure user requests
|
||||
|
||||
### 📊 **Monitoring Setup**
|
||||
1. **Tautulli** - Connect to Plex for detailed statistics
|
||||
2. **Health Dashboard** - SSH to VPS and run `health` command
|
||||
3. **VPN Status** - Check `docker logs gluetun` for VPN connection
|
||||
|
||||
### 🔐 **Security Setup**
|
||||
1. **Change Default Passwords**: qBittorrent admin password
|
||||
2. **Enable Authentication**: Set up auth on services that support it
|
||||
3. **Review Firewall**: Check UFW status with `sudo ufw status`
|
||||
4. **Monitor Logs**: Check `/var/log/arrs/` for monitoring logs
|
||||
|
||||
## 📞 **Support & Troubleshooting**
|
||||
|
||||
If you can't access a service:
|
||||
|
||||
1. **Check Service Status**: `docker ps` to see running containers
|
||||
2. **Check Logs**: `docker logs [service-name]` for error messages
|
||||
3. **Check Firewall**: `sudo ufw status` to verify port access
|
||||
4. **Check Tailscale**: Ensure Tailscale is connected on your device
|
||||
5. **Health Dashboard**: Run `/usr/local/bin/health-dashboard.sh` on VPS
|
||||
|
||||
## 🔧 **Specific Service Troubleshooting**
|
||||
|
||||
### 🚨 **TubeArchivist Not Loading**
|
||||
If TubeArchivist (http://YOUR_TAILSCALE_IP:8000) shows connection errors:
|
||||
|
||||
```bash
|
||||
# Check all TubeArchivist containers
|
||||
docker ps | grep tubearchivist
|
||||
|
||||
# Restart in correct order (dependencies first)
|
||||
docker-compose restart tubearchivist-es
|
||||
sleep 30
|
||||
docker-compose restart tubearchivist-redis
|
||||
sleep 10
|
||||
docker-compose restart tubearchivist
|
||||
|
||||
# Check logs if still not working
|
||||
docker-compose logs -f tubearchivist
|
||||
```
|
||||
|
||||
### 🔄 **Download Client Port Mix-up**
|
||||
If ports are swapped (SABnzbd on 8081, qBittorrent on 8080):
|
||||
|
||||
```bash
|
||||
# Restart VPN container and download clients
|
||||
docker-compose restart gluetun
|
||||
sleep 30
|
||||
docker-compose restart qbittorrent sabnzbd
|
||||
|
||||
# Verify correct mapping
|
||||
curl -I http://YOUR_TAILSCALE_IP:8080 # Should show SABnzbd
|
||||
curl -I http://YOUR_TAILSCALE_IP:8081 # Should show qBittorrent
|
||||
```
|
||||
|
||||
### 🌐 **VPN Connection Issues**
|
||||
If download clients show "Unauthorized" or won't load:
|
||||
|
||||
```bash
|
||||
# Check VPN status
|
||||
docker-compose logs gluetun | tail -20
|
||||
|
||||
# Restart entire VPN stack
|
||||
docker-compose down qbittorrent sabnzbd gluetun
|
||||
docker-compose up -d gluetun
|
||||
sleep 60
|
||||
docker-compose up -d qbittorrent sabnzbd
|
||||
```
|
||||
|
||||
## 🎉 **Enjoy Your Media Stack!**
|
||||
|
||||
Your complete Arrs media management stack is now accessible via Tailscale at `YOUR_TAILSCALE_IP`. All services are running and ready for configuration!
|
||||
|
||||
**Next Steps**:
|
||||
1. Configure Prowlarr with your preferred indexers
|
||||
2. Set up Sonarr/Radarr with your media preferences
|
||||
3. Configure download clients with VPN protection
|
||||
4. Add media libraries to Plex
|
||||
5. Set up Jellyseerr for user requests
|
||||
|
||||
Happy streaming! 🍿📺🎵
|
||||
823
docs/TROUBLESHOOTING.md
Normal file
823
docs/TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,823 @@
|
||||
# Troubleshooting Guide
|
||||
|
||||
This guide covers common issues you might encounter when deploying and running the Arrs media stack, along with step-by-step solutions.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Quick Diagnostics](#quick-diagnostics)
|
||||
2. [Deployment Issues](#deployment-issues)
|
||||
3. [Service Issues](#service-issues)
|
||||
4. [Network and Connectivity](#network-and-connectivity)
|
||||
5. [Storage and Permissions](#storage-and-permissions)
|
||||
6. [VPN Issues](#vpn-issues)
|
||||
7. [Performance Issues](#performance-issues)
|
||||
8. [Backup and Recovery](#backup-and-recovery)
|
||||
9. [Getting Help](#getting-help)
|
||||
|
||||
## Quick Diagnostics
|
||||
|
||||
### Essential Commands
|
||||
|
||||
```bash
|
||||
# Check all container status
|
||||
docker ps -a
|
||||
|
||||
# Check system resources
|
||||
htop
|
||||
df -h
|
||||
|
||||
# Check logs for all services
|
||||
docker-compose logs --tail=50
|
||||
|
||||
# Check specific service logs
|
||||
docker logs [service_name] --tail=50
|
||||
|
||||
# Test network connectivity
|
||||
ping google.com
|
||||
curl -I https://google.com
|
||||
```
|
||||
|
||||
### Health Check Script
|
||||
|
||||
Create a quick health check script:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Save as ~/check_health.sh
|
||||
|
||||
echo "=== System Resources ==="
|
||||
df -h | grep -E "(Filesystem|/dev/)"
|
||||
free -h
|
||||
echo ""
|
||||
|
||||
echo "=== Docker Status ==="
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
echo ""
|
||||
|
||||
echo "=== Service Health ==="
|
||||
services=("sonarr" "radarr" "lidarr" "bazarr" "prowlarr" "qbittorrent" "plex" "tubearchivist" "tubearchivist-es" "tubearchivist-redis" "jellyseerr" "tautulli")
|
||||
for service in "${services[@]}"; do
|
||||
if docker ps | grep -q $service; then
|
||||
echo "✅ $service: Running"
|
||||
else
|
||||
echo "❌ $service: Not running"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
Make it executable and run:
|
||||
```bash
|
||||
chmod +x ~/check_health.sh
|
||||
~/check_health.sh
|
||||
```
|
||||
|
||||
## Deployment Issues
|
||||
|
||||
### Ansible Playbook Fails
|
||||
|
||||
#### Issue: "Permission denied" errors
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
TASK [Create docker user] ****
|
||||
fatal: [localhost]: FAILED! => {"msg": "Permission denied"}
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
1. Ensure you're running as a user with sudo privileges:
|
||||
```bash
|
||||
sudo -v # Test sudo access
|
||||
```
|
||||
|
||||
2. If using a non-root user, ensure they're in the sudo group:
|
||||
```bash
|
||||
sudo usermod -aG sudo $USER
|
||||
# Log out and back in
|
||||
```
|
||||
|
||||
3. Run with explicit sudo if needed:
|
||||
```bash
|
||||
ansible-playbook -i inventory/hosts site.yml --become --ask-become-pass
|
||||
```
|
||||
|
||||
#### Issue: "Docker not found" after installation
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
TASK [Start Docker service] ****
|
||||
fatal: [localhost]: FAILED! => {"msg": "Could not find the requested service docker"}
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
1. Manually install Docker:
|
||||
```bash
|
||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||
sudo sh get-docker.sh
|
||||
sudo usermod -aG docker $USER
|
||||
# Log out and back in
|
||||
```
|
||||
|
||||
2. Restart the deployment:
|
||||
```bash
|
||||
ansible-playbook -i inventory/hosts site.yml
|
||||
```
|
||||
|
||||
#### Issue: "Port already in use"
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
ERROR: for sonarr Cannot start service sonarr: driver failed programming external connectivity on endpoint sonarr: Bind for 0.0.0.0:8989 failed: port is already allocated
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
1. Check what's using the port:
|
||||
```bash
|
||||
sudo netstat -tulpn | grep :8989
|
||||
sudo lsof -i :8989
|
||||
```
|
||||
|
||||
2. Stop the conflicting service or change ports in `group_vars/all.yml`:
|
||||
```yaml
|
||||
ports:
|
||||
sonarr: 8990 # Changed from 8989
|
||||
```
|
||||
|
||||
3. Redeploy:
|
||||
```bash
|
||||
ansible-playbook -i inventory/hosts site.yml
|
||||
```
|
||||
|
||||
### Configuration File Issues
|
||||
|
||||
#### Issue: YAML syntax errors
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
ERROR! Syntax Error while loading YAML.
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
1. Validate YAML syntax:
|
||||
```bash
|
||||
python3 -c "import yaml; yaml.safe_load(open('group_vars/all.yml'))"
|
||||
```
|
||||
|
||||
2. Common YAML mistakes:
|
||||
- Missing quotes around special characters
|
||||
- Incorrect indentation (use spaces, not tabs)
|
||||
- Missing colons after keys
|
||||
|
||||
3. Use a YAML validator online or in your editor
|
||||
|
||||
#### Issue: Undefined variables
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
AnsibleUndefinedVariable: 'vpn_provider' is undefined
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
1. Check if variable is defined in `group_vars/all.yml`
|
||||
2. Ensure proper indentation and spelling
|
||||
3. Add missing variables:
|
||||
```yaml
|
||||
vpn_provider: "nordvpn" # Add if missing
|
||||
```
|
||||
|
||||
## Service Issues
|
||||
|
||||
### Services Won't Start
|
||||
|
||||
#### Issue: Container exits immediately
|
||||
|
||||
**Check logs:**
|
||||
```bash
|
||||
docker logs [container_name]
|
||||
```
|
||||
|
||||
**Common causes and solutions:**
|
||||
|
||||
1. **Permission issues:**
|
||||
```bash
|
||||
# Fix ownership
|
||||
sudo chown -R 1000:1000 /home/arrs/docker
|
||||
sudo chown -R 1000:1000 /home/arrs/media
|
||||
```
|
||||
|
||||
2. **Missing directories:**
|
||||
```bash
|
||||
# Create missing directories
|
||||
mkdir -p /home/arrs/media/{movies,tv,music,downloads}
|
||||
mkdir -p /home/arrs/docker/{sonarr,radarr,lidarr,bazarr,prowlarr,qbittorrent}
|
||||
```
|
||||
|
||||
3. **Configuration file corruption:**
|
||||
```bash
|
||||
# Remove corrupted config and restart
|
||||
sudo rm -rf /home/arrs/docker/sonarr/config.xml
|
||||
docker restart sonarr
|
||||
```
|
||||
|
||||
#### Issue: Service starts but web interface not accessible
|
||||
|
||||
**Symptoms:**
|
||||
- Container shows as running
|
||||
- Can't access web interface
|
||||
|
||||
**Solutions:**
|
||||
1. Check if service is listening on correct port:
|
||||
```bash
|
||||
docker exec sonarr netstat -tulpn | grep :8989
|
||||
```
|
||||
|
||||
2. Check firewall:
|
||||
```bash
|
||||
sudo ufw status
|
||||
sudo ufw allow 8989 # Open required port
|
||||
```
|
||||
|
||||
3. Check if service is bound to localhost only:
|
||||
```bash
|
||||
docker logs sonarr | grep -i "listening\|bind"
|
||||
```
|
||||
|
||||
### Database Issues
|
||||
|
||||
#### Issue: Sonarr/Radarr database corruption
|
||||
|
||||
**Symptoms:**
|
||||
- Service won't start
|
||||
- Logs show database errors
|
||||
- Web interface shows errors
|
||||
|
||||
**Solutions:**
|
||||
1. **Backup current database:**
|
||||
```bash
|
||||
cp /home/arrs/docker/sonarr/sonarr.db /home/arrs/docker/sonarr/sonarr.db.backup
|
||||
```
|
||||
|
||||
2. **Try database repair:**
|
||||
```bash
|
||||
# Install sqlite3
|
||||
sudo apt install sqlite3
|
||||
|
||||
# Check database integrity
|
||||
sqlite3 /home/arrs/docker/sonarr/sonarr.db "PRAGMA integrity_check;"
|
||||
|
||||
# Repair if needed
|
||||
sqlite3 /home/arrs/docker/sonarr/sonarr.db ".recover" | sqlite3 /home/arrs/docker/sonarr/sonarr_recovered.db
|
||||
```
|
||||
|
||||
3. **Restore from backup:**
|
||||
```bash
|
||||
# Stop service
|
||||
docker stop sonarr
|
||||
|
||||
# Restore backup
|
||||
cp /home/arrs/docker/sonarr/sonarr.db.backup /home/arrs/docker/sonarr/sonarr.db
|
||||
|
||||
# Start service
|
||||
docker start sonarr
|
||||
```
|
||||
|
||||
## Network and Connectivity
|
||||
|
||||
### Can't Access Services from Outside
|
||||
|
||||
#### Issue: Services only accessible from localhost
|
||||
|
||||
**Solutions:**
|
||||
1. **Check Docker network configuration:**
|
||||
```bash
|
||||
docker network ls
|
||||
docker network inspect arrs_network
|
||||
```
|
||||
|
||||
2. **Verify port bindings:**
|
||||
```bash
|
||||
docker port sonarr
|
||||
```
|
||||
|
||||
3. **Check VPS firewall:**
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo ufw status
|
||||
sudo ufw allow 8989
|
||||
|
||||
# CentOS/RHEL
|
||||
sudo firewall-cmd --list-ports
|
||||
sudo firewall-cmd --add-port=8989/tcp --permanent
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
4. **Check cloud provider firewall:**
|
||||
- AWS: Security Groups
|
||||
- DigitalOcean: Cloud Firewalls
|
||||
- Google Cloud: VPC Firewall Rules
|
||||
|
||||
### DNS Resolution Issues
|
||||
|
||||
#### Issue: Services can't resolve external domains
|
||||
|
||||
**Symptoms:**
|
||||
- Can't download metadata
|
||||
- Indexer tests fail
|
||||
- Updates don't work
|
||||
|
||||
**Solutions:**
|
||||
1. **Check DNS in containers:**
|
||||
```bash
|
||||
docker exec sonarr nslookup google.com
|
||||
docker exec sonarr cat /etc/resolv.conf
|
||||
```
|
||||
|
||||
2. **Fix DNS configuration:**
|
||||
```bash
|
||||
# Edit Docker daemon configuration
|
||||
sudo nano /etc/docker/daemon.json
|
||||
```
|
||||
|
||||
Add:
|
||||
```json
|
||||
{
|
||||
"dns": ["8.8.8.8", "1.1.1.1"]
|
||||
}
|
||||
```
|
||||
|
||||
Restart Docker:
|
||||
```bash
|
||||
sudo systemctl restart docker
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## Storage and Permissions
|
||||
|
||||
### Permission Denied Errors
|
||||
|
||||
#### Issue: Services can't write to media directories
|
||||
|
||||
**Symptoms:**
|
||||
- Downloads fail
|
||||
- Can't move files
|
||||
- Import errors
|
||||
|
||||
**Solutions:**
|
||||
1. **Check current permissions:**
|
||||
```bash
|
||||
ls -la /home/arrs/media/
|
||||
ls -la /home/arrs/docker/
|
||||
```
|
||||
|
||||
2. **Fix ownership:**
|
||||
```bash
|
||||
# Get user/group IDs
|
||||
id arrs
|
||||
|
||||
# Fix ownership (replace 1000:1000 with actual IDs)
|
||||
sudo chown -R 1000:1000 /home/arrs/media
|
||||
sudo chown -R 1000:1000 /home/arrs/docker
|
||||
```
|
||||
|
||||
3. **Fix permissions:**
|
||||
```bash
|
||||
sudo chmod -R 755 /home/arrs/media
|
||||
sudo chmod -R 755 /home/arrs/docker
|
||||
```
|
||||
|
||||
4. **Verify container user mapping:**
|
||||
```bash
|
||||
docker exec sonarr id
|
||||
```
|
||||
|
||||
### Disk Space Issues
|
||||
|
||||
#### Issue: No space left on device
|
||||
|
||||
**Solutions:**
|
||||
1. **Check disk usage:**
|
||||
```bash
|
||||
df -h
|
||||
du -sh /home/arrs/* | sort -hr
|
||||
```
|
||||
|
||||
2. **Clean up Docker:**
|
||||
```bash
|
||||
# Remove unused containers, networks, images
|
||||
docker system prune -a
|
||||
|
||||
# Remove unused volumes (CAREFUL!)
|
||||
docker volume prune
|
||||
```
|
||||
|
||||
3. **Clean up logs:**
|
||||
```bash
|
||||
# Truncate large log files
|
||||
sudo truncate -s 0 /var/log/syslog
|
||||
sudo truncate -s 0 /var/log/kern.log
|
||||
|
||||
# Clean Docker logs
|
||||
docker logs sonarr 2>/dev/null | wc -l # Check log size
|
||||
sudo sh -c 'echo "" > $(docker inspect --format="{{.LogPath}}" sonarr)'
|
||||
```
|
||||
|
||||
4. **Move media to external storage:**
|
||||
```bash
|
||||
# Mount additional storage
|
||||
sudo mkdir /mnt/media
|
||||
sudo mount /dev/sdb1 /mnt/media
|
||||
|
||||
# Update configuration
|
||||
nano group_vars/all.yml
|
||||
# Change media_root: "/mnt/media"
|
||||
```
|
||||
|
||||
## TubeArchivist Issues
|
||||
|
||||
### TubeArchivist Won't Start
|
||||
|
||||
#### Issue: Elasticsearch container fails to start
|
||||
|
||||
**Symptoms:**
|
||||
- TubeArchivist shows "Elasticsearch connection failed"
|
||||
- Elasticsearch container exits with memory errors
|
||||
- Web interface shows database connection errors
|
||||
|
||||
**Solutions:**
|
||||
1. **Increase memory allocation:**
|
||||
```bash
|
||||
# Check available memory
|
||||
free -h
|
||||
|
||||
# If less than 4GB available, reduce ES memory in docker-compose.yml
|
||||
# Change ES_JAVA_OPTS from -Xms1g -Xmx1g to -Xms512m -Xmx512m
|
||||
```
|
||||
|
||||
2. **Fix Elasticsearch permissions:**
|
||||
```bash
|
||||
sudo chown -R 1000:1000 /home/arrs/docker/tubearchivist/es
|
||||
sudo chmod -R 755 /home/arrs/docker/tubearchivist/es
|
||||
```
|
||||
|
||||
3. **Check disk space:**
|
||||
```bash
|
||||
df -h /home/arrs/docker/tubearchivist/
|
||||
```
|
||||
|
||||
#### Issue: Downloads fail or get stuck
|
||||
|
||||
**Symptoms:**
|
||||
- Videos remain in "Pending" status
|
||||
- Download queue shows errors
|
||||
- yt-dlp errors in logs
|
||||
|
||||
**Solutions:**
|
||||
1. **Update yt-dlp:**
|
||||
```bash
|
||||
docker exec tubearchivist pip install --upgrade yt-dlp
|
||||
docker restart tubearchivist
|
||||
```
|
||||
|
||||
2. **Check YouTube channel/video availability:**
|
||||
- Verify the channel/video is still available
|
||||
- Check if the channel has geographic restrictions
|
||||
- Try downloading a different video to test
|
||||
|
||||
3. **Clear download queue:**
|
||||
```bash
|
||||
# Access TubeArchivist web interface
|
||||
# Go to Downloads → Queue → Clear Failed
|
||||
```
|
||||
|
||||
4. **Check storage space:**
|
||||
```bash
|
||||
df -h /home/arrs/media/youtube
|
||||
```
|
||||
|
||||
#### Issue: Videos won't play or thumbnails missing
|
||||
|
||||
**Symptoms:**
|
||||
- Videos show but won't play
|
||||
- Missing thumbnails
|
||||
- Playback errors
|
||||
|
||||
**Solutions:**
|
||||
1. **Check file permissions:**
|
||||
```bash
|
||||
ls -la /home/arrs/media/youtube/
|
||||
sudo chown -R 1000:1000 /home/arrs/media/youtube
|
||||
```
|
||||
|
||||
2. **Regenerate thumbnails:**
|
||||
- Go to Settings → Application → Reindex
|
||||
- Select "Thumbnails" and run reindex
|
||||
|
||||
3. **Check video file integrity:**
|
||||
```bash
|
||||
# Test video files
|
||||
find /home/arrs/media/youtube -name "*.mp4" -exec file {} \;
|
||||
```
|
||||
|
||||
### TubeArchivist Performance Issues
|
||||
|
||||
#### Issue: Slow downloads or high CPU usage
|
||||
|
||||
**Solutions:**
|
||||
1. **Limit concurrent downloads:**
|
||||
- Go to Settings → Download → Max concurrent downloads
|
||||
- Reduce from default (4) to 1-2 for lower-end systems
|
||||
|
||||
2. **Adjust video quality:**
|
||||
- Go to Settings → Download → Video quality
|
||||
- Choose lower quality (720p instead of 1080p) to reduce processing
|
||||
|
||||
3. **Schedule downloads during off-peak hours:**
|
||||
- Go to Settings → Scheduling
|
||||
- Set download windows for low-usage periods
|
||||
|
||||
#### Issue: Database performance problems
|
||||
|
||||
**Solutions:**
|
||||
1. **Optimize Elasticsearch:**
|
||||
```bash
|
||||
# Increase refresh interval
|
||||
docker exec tubearchivist-es curl -X PUT "localhost:9200/_settings" -H 'Content-Type: application/json' -d'
|
||||
{
|
||||
"index": {
|
||||
"refresh_interval": "30s"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
2. **Clean up old data:**
|
||||
- Go to Settings → Application → Cleanup
|
||||
- Remove old downloads and unused thumbnails
|
||||
|
||||
## VPN Issues
|
||||
|
||||
### VPN Won't Connect
|
||||
|
||||
#### Issue: Gluetun fails to connect
|
||||
|
||||
**Check logs:**
|
||||
```bash
|
||||
docker logs gluetun --tail=50
|
||||
```
|
||||
|
||||
**Common solutions:**
|
||||
|
||||
1. **Wrong credentials:**
|
||||
```yaml
|
||||
# Verify in group_vars/all.yml
|
||||
openvpn_user: "correct_username"
|
||||
openvpn_password: "correct_password"
|
||||
```
|
||||
|
||||
2. **Unsupported server location:**
|
||||
```yaml
|
||||
# Try different countries
|
||||
vpn_countries: "Netherlands,Germany"
|
||||
```
|
||||
|
||||
3. **Provider API issues:**
|
||||
```bash
|
||||
# Try manual server selection
|
||||
vpn_server_hostnames: "nl123.nordvpn.com"
|
||||
```
|
||||
|
||||
#### Issue: qBittorrent can't connect through VPN
|
||||
|
||||
**Solutions:**
|
||||
1. **Check network mode:**
|
||||
```bash
|
||||
docker inspect qbittorrent | grep NetworkMode
|
||||
# Should show: "NetworkMode": "service:gluetun"
|
||||
```
|
||||
|
||||
2. **Test connectivity:**
|
||||
```bash
|
||||
# Test from qBittorrent container
|
||||
docker exec qbittorrent curl -s https://ipinfo.io/ip
|
||||
```
|
||||
|
||||
3. **Restart VPN stack:**
|
||||
```bash
|
||||
docker restart gluetun
|
||||
docker restart qbittorrent
|
||||
```
|
||||
|
||||
## Performance Issues
|
||||
|
||||
### Slow Performance
|
||||
|
||||
#### Issue: Services are slow or unresponsive
|
||||
|
||||
**Solutions:**
|
||||
1. **Check system resources:**
|
||||
```bash
|
||||
htop
|
||||
iotop # Install with: sudo apt install iotop
|
||||
```
|
||||
|
||||
2. **Optimize Docker:**
|
||||
```bash
|
||||
# Limit container resources in docker-compose.yml
|
||||
services:
|
||||
sonarr:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 256M
|
||||
```
|
||||
|
||||
3. **Optimize database:**
|
||||
```bash
|
||||
# Vacuum SQLite databases
|
||||
sqlite3 /home/arrs/docker/sonarr/sonarr.db "VACUUM;"
|
||||
sqlite3 /home/arrs/docker/radarr/radarr.db "VACUUM;"
|
||||
```
|
||||
|
||||
4. **Check disk I/O:**
|
||||
```bash
|
||||
# Test disk speed
|
||||
dd if=/dev/zero of=/tmp/test bs=1M count=1000
|
||||
rm /tmp/test
|
||||
```
|
||||
|
||||
### High CPU Usage
|
||||
|
||||
#### Issue: Containers using too much CPU
|
||||
|
||||
**Solutions:**
|
||||
1. **Identify problematic containers:**
|
||||
```bash
|
||||
docker stats
|
||||
```
|
||||
|
||||
2. **Check for runaway processes:**
|
||||
```bash
|
||||
docker exec sonarr ps aux
|
||||
```
|
||||
|
||||
3. **Limit CPU usage:**
|
||||
```yaml
|
||||
# In docker-compose.yml
|
||||
services:
|
||||
sonarr:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5' # Limit to 50% of one CPU core
|
||||
```
|
||||
|
||||
## Backup and Recovery
|
||||
|
||||
### Backup Issues
|
||||
|
||||
#### Issue: Backup script fails
|
||||
|
||||
**Check backup logs:**
|
||||
```bash
|
||||
# Check if backup script exists
|
||||
ls -la /home/arrs/scripts/backup.sh
|
||||
|
||||
# Check backup logs
|
||||
tail -f /var/log/arrs-backup.log
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
1. **Fix permissions:**
|
||||
```bash
|
||||
chmod +x /home/arrs/scripts/backup.sh
|
||||
```
|
||||
|
||||
2. **Test backup manually:**
|
||||
```bash
|
||||
sudo /home/arrs/scripts/backup.sh
|
||||
```
|
||||
|
||||
3. **Check backup destination:**
|
||||
```bash
|
||||
df -h /home/arrs/backups
|
||||
```
|
||||
|
||||
### Recovery Procedures
|
||||
|
||||
#### Issue: Need to restore from backup
|
||||
|
||||
**Steps:**
|
||||
1. **Stop all services:**
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
2. **Restore configuration:**
|
||||
```bash
|
||||
# Extract backup
|
||||
tar -xzf /home/arrs/backups/arrs-backup-YYYYMMDD.tar.gz -C /home/arrs/
|
||||
```
|
||||
|
||||
3. **Fix permissions:**
|
||||
```bash
|
||||
sudo chown -R 1000:1000 /home/arrs/docker
|
||||
```
|
||||
|
||||
4. **Start services:**
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## Getting Help
|
||||
|
||||
### Before Asking for Help
|
||||
|
||||
1. **Check logs:**
|
||||
```bash
|
||||
docker logs [service_name] --tail=100
|
||||
```
|
||||
|
||||
2. **Gather system information:**
|
||||
```bash
|
||||
# Create debug info
|
||||
echo "=== System Info ===" > debug.txt
|
||||
uname -a >> debug.txt
|
||||
docker --version >> debug.txt
|
||||
docker-compose --version >> debug.txt
|
||||
|
||||
echo "=== Container Status ===" >> debug.txt
|
||||
docker ps -a >> debug.txt
|
||||
|
||||
echo "=== Disk Usage ===" >> debug.txt
|
||||
df -h >> debug.txt
|
||||
|
||||
echo "=== Memory Usage ===" >> debug.txt
|
||||
free -h >> debug.txt
|
||||
```
|
||||
|
||||
3. **Sanitize sensitive information:**
|
||||
- Remove passwords, API keys, personal paths
|
||||
- Replace IP addresses with placeholders
|
||||
|
||||
### Where to Get Help
|
||||
|
||||
1. **GitHub Issues**: Create an issue with:
|
||||
- Clear description of the problem
|
||||
- Steps to reproduce
|
||||
- Error messages
|
||||
- System information
|
||||
- Configuration (sanitized)
|
||||
|
||||
2. **Community Forums**:
|
||||
- r/selfhosted
|
||||
- r/sonarr, r/radarr
|
||||
- Discord servers for specific applications
|
||||
|
||||
3. **Documentation**:
|
||||
- Official documentation for each service
|
||||
- Docker documentation
|
||||
- Ansible documentation
|
||||
|
||||
### Common Support Questions
|
||||
|
||||
**Q: "It doesn't work"**
|
||||
A: Please provide specific error messages and logs.
|
||||
|
||||
**Q: "Can't access from outside"**
|
||||
A: Check firewall settings and port configurations.
|
||||
|
||||
**Q: "Downloads don't start"**
|
||||
A: Check indexer configuration and download client settings.
|
||||
|
||||
**Q: "VPN not working"**
|
||||
A: Verify credentials and check Gluetun logs.
|
||||
|
||||
**Q: "Running out of space"**
|
||||
A: Clean up Docker images and logs, consider external storage.
|
||||
|
||||
### Emergency Recovery
|
||||
|
||||
If everything breaks:
|
||||
|
||||
1. **Stop all services:**
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
2. **Backup current state:**
|
||||
```bash
|
||||
sudo tar -czf emergency-backup-$(date +%Y%m%d).tar.gz /home/arrs/docker
|
||||
```
|
||||
|
||||
3. **Reset to clean state:**
|
||||
```bash
|
||||
# Remove all containers and volumes
|
||||
docker system prune -a --volumes
|
||||
|
||||
# Redeploy
|
||||
ansible-playbook -i inventory/hosts site.yml
|
||||
```
|
||||
|
||||
4. **Restore data from backups if needed**
|
||||
|
||||
Remember: Most issues are fixable with patience and systematic troubleshooting. Don't panic, and always backup before making major changes!
|
||||
495
docs/VPN_CONFIGURATION.md
Normal file
495
docs/VPN_CONFIGURATION.md
Normal file
@@ -0,0 +1,495 @@
|
||||
# VPN Configuration Guide
|
||||
|
||||
This guide provides detailed configuration examples for popular VPN providers with the Arrs media stack. The VPN integration uses Gluetun to route qBittorrent traffic through your VPN provider for enhanced privacy and security.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [General Configuration](#general-configuration)
|
||||
3. [Provider-Specific Configurations](#provider-specific-configurations)
|
||||
4. [Testing Your VPN Connection](#testing-your-vpn-connection)
|
||||
5. [Troubleshooting](#troubleshooting)
|
||||
6. [Advanced Configuration](#advanced-configuration)
|
||||
|
||||
## Overview
|
||||
|
||||
### What Gets Protected
|
||||
|
||||
When VPN is enabled:
|
||||
- ✅ **qBittorrent**: All torrent traffic routed through VPN
|
||||
- ✅ **SABnzbd**: Optionally routed through VPN (configurable)
|
||||
- ❌ **Other services**: Sonarr, Radarr, Plex, etc. use direct connection
|
||||
|
||||
### VPN Technologies Supported
|
||||
|
||||
- **OpenVPN**: Most common, works with most providers
|
||||
- **WireGuard**: Faster, more modern protocol (where supported)
|
||||
|
||||
## General Configuration
|
||||
|
||||
### Basic VPN Settings
|
||||
|
||||
Edit `group_vars/all.yml`:
|
||||
|
||||
```yaml
|
||||
# =============================================================================
|
||||
# VPN CONFIGURATION (for qBittorrent)
|
||||
# =============================================================================
|
||||
|
||||
# Enable VPN for download clients
|
||||
vpn_enabled: true
|
||||
|
||||
# Optionally route SABnzbd through VPN as well (some prefer Usenet through VPN)
|
||||
sabnzbd_vpn_enabled: false # Set to true if you want SABnzbd through VPN
|
||||
|
||||
# VPN Provider (see provider list below)
|
||||
vpn_provider: "nordvpn" # Change to your provider
|
||||
|
||||
# VPN Type: openvpn or wireguard
|
||||
vpn_type: "openvpn"
|
||||
|
||||
# OpenVPN credentials (if using OpenVPN)
|
||||
openvpn_user: "your_username"
|
||||
openvpn_password: "your_password"
|
||||
|
||||
# WireGuard configuration (if using WireGuard)
|
||||
wireguard_private_key: ""
|
||||
wireguard_addresses: ""
|
||||
|
||||
# VPN server countries (comma-separated)
|
||||
vpn_countries: "Netherlands,Germany"
|
||||
```
|
||||
|
||||
## Provider-Specific Configurations
|
||||
|
||||
### NordVPN
|
||||
|
||||
**Requirements:**
|
||||
- NordVPN subscription
|
||||
- Service credentials (not your regular login)
|
||||
|
||||
**Configuration:**
|
||||
|
||||
```yaml
|
||||
vpn_enabled: true
|
||||
vpn_provider: "nordvpn"
|
||||
vpn_type: "openvpn"
|
||||
openvpn_user: "your_service_username"
|
||||
openvpn_password: "your_service_password"
|
||||
vpn_countries: "Netherlands,Germany,Switzerland"
|
||||
```
|
||||
|
||||
**Getting Service Credentials:**
|
||||
1. Log into your NordVPN account
|
||||
2. Go to Services → NordVPN → Manual Setup
|
||||
3. Generate service credentials
|
||||
4. Use these credentials (not your regular login)
|
||||
|
||||
**Recommended Countries:**
|
||||
- Netherlands, Germany, Switzerland (good for privacy)
|
||||
- Romania, Moldova (good speeds)
|
||||
|
||||
### ExpressVPN
|
||||
|
||||
**Requirements:**
|
||||
- ExpressVPN subscription
|
||||
- Manual configuration credentials
|
||||
|
||||
**Configuration:**
|
||||
|
||||
```yaml
|
||||
vpn_enabled: true
|
||||
vpn_provider: "expressvpn"
|
||||
vpn_type: "openvpn"
|
||||
openvpn_user: "your_username"
|
||||
openvpn_password: "your_password"
|
||||
vpn_countries: "Netherlands,Germany"
|
||||
```
|
||||
|
||||
**Getting Credentials:**
|
||||
1. Log into ExpressVPN account
|
||||
2. Go to Set Up ExpressVPN → Manual Config
|
||||
3. Select OpenVPN
|
||||
4. Download credentials or note username/password
|
||||
|
||||
### Surfshark
|
||||
|
||||
**Requirements:**
|
||||
- Surfshark subscription
|
||||
- Service credentials
|
||||
|
||||
**Configuration:**
|
||||
|
||||
```yaml
|
||||
vpn_enabled: true
|
||||
vpn_provider: "surfshark"
|
||||
vpn_type: "openvpn"
|
||||
openvpn_user: "your_service_username"
|
||||
openvpn_password: "your_service_password"
|
||||
vpn_countries: "Netherlands,Germany"
|
||||
```
|
||||
|
||||
**Getting Service Credentials:**
|
||||
1. Log into Surfshark account
|
||||
2. Go to VPN → Manual setup → OpenVPN
|
||||
3. Generate or view service credentials
|
||||
|
||||
### Private Internet Access (PIA)
|
||||
|
||||
**Requirements:**
|
||||
- PIA subscription
|
||||
- Username and password
|
||||
|
||||
**Configuration:**
|
||||
|
||||
```yaml
|
||||
vpn_enabled: true
|
||||
vpn_provider: "private internet access"
|
||||
vpn_type: "openvpn"
|
||||
openvpn_user: "your_pia_username"
|
||||
openvpn_password: "your_pia_password"
|
||||
vpn_countries: "Netherlands,Germany,Switzerland"
|
||||
```
|
||||
|
||||
**Note:** Use your regular PIA login credentials.
|
||||
|
||||
### CyberGhost
|
||||
|
||||
**Requirements:**
|
||||
- CyberGhost subscription
|
||||
- OpenVPN credentials
|
||||
|
||||
**Configuration:**
|
||||
|
||||
```yaml
|
||||
vpn_enabled: true
|
||||
vpn_provider: "cyberghost"
|
||||
vpn_type: "openvpn"
|
||||
openvpn_user: "your_username"
|
||||
openvpn_password: "your_password"
|
||||
vpn_countries: "Netherlands,Germany"
|
||||
```
|
||||
|
||||
**Getting Credentials:**
|
||||
1. Log into CyberGhost account
|
||||
2. Go to My Account → VPN → Configure new device
|
||||
3. Select OpenVPN and download configuration
|
||||
|
||||
### ProtonVPN
|
||||
|
||||
**Requirements:**
|
||||
- ProtonVPN subscription (Plus or higher for P2P)
|
||||
- OpenVPN credentials
|
||||
|
||||
**Configuration:**
|
||||
|
||||
```yaml
|
||||
vpn_enabled: true
|
||||
vpn_provider: "protonvpn"
|
||||
vpn_type: "openvpn"
|
||||
openvpn_user: "your_openvpn_username"
|
||||
openvpn_password: "your_openvpn_password"
|
||||
vpn_countries: "Netherlands,Germany,Switzerland"
|
||||
```
|
||||
|
||||
**Getting Credentials:**
|
||||
1. Log into ProtonVPN account
|
||||
2. Go to Account → OpenVPN/IKEv2 username
|
||||
3. Generate OpenVPN credentials
|
||||
|
||||
**Important:** Only Plus and Visionary plans support P2P traffic.
|
||||
|
||||
### Mullvad
|
||||
|
||||
**Requirements:**
|
||||
- Mullvad subscription
|
||||
- Account number
|
||||
|
||||
**OpenVPN Configuration:**
|
||||
|
||||
```yaml
|
||||
vpn_enabled: true
|
||||
vpn_provider: "mullvad"
|
||||
vpn_type: "openvpn"
|
||||
openvpn_user: "your_account_number"
|
||||
openvpn_password: "m" # Always "m" for Mullvad
|
||||
vpn_countries: "Netherlands,Germany,Switzerland"
|
||||
```
|
||||
|
||||
**WireGuard Configuration (Recommended):**
|
||||
|
||||
```yaml
|
||||
vpn_enabled: true
|
||||
vpn_provider: "mullvad"
|
||||
vpn_type: "wireguard"
|
||||
wireguard_private_key: "your_private_key"
|
||||
wireguard_addresses: "10.x.x.x/32"
|
||||
vpn_countries: "Netherlands,Germany,Switzerland"
|
||||
```
|
||||
|
||||
**Getting WireGuard Keys:**
|
||||
1. Log into Mullvad account
|
||||
2. Go to WireGuard configuration
|
||||
3. Generate a key pair
|
||||
4. Note the private key and IP address
|
||||
|
||||
### Windscribe
|
||||
|
||||
**Requirements:**
|
||||
- Windscribe Pro subscription
|
||||
- OpenVPN credentials
|
||||
|
||||
**Configuration:**
|
||||
|
||||
```yaml
|
||||
vpn_enabled: true
|
||||
vpn_provider: "windscribe"
|
||||
vpn_type: "openvpn"
|
||||
openvpn_user: "your_username"
|
||||
openvpn_password: "your_password"
|
||||
vpn_countries: "Netherlands,Germany"
|
||||
```
|
||||
|
||||
**Getting Credentials:**
|
||||
1. Log into Windscribe account
|
||||
2. Go to Setup → Config Generators → OpenVPN
|
||||
3. Generate configuration with credentials
|
||||
|
||||
## Testing Your VPN Connection
|
||||
|
||||
### Step 1: Deploy with VPN Enabled
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventory/hosts site.yml
|
||||
```
|
||||
|
||||
### Step 2: Check Gluetun Connection
|
||||
|
||||
```bash
|
||||
# Check Gluetun logs
|
||||
docker logs gluetun
|
||||
|
||||
# Look for successful connection messages
|
||||
docker logs gluetun | grep -i "connected"
|
||||
```
|
||||
|
||||
### Step 3: Verify qBittorrent IP
|
||||
|
||||
1. Go to qBittorrent web interface: `http://YOUR_VPS_IP:8080`
|
||||
2. Check the connection status
|
||||
3. Use a torrent IP checker to verify your IP has changed
|
||||
|
||||
### Step 4: Test IP Leak Protection
|
||||
|
||||
```bash
|
||||
# Check what IP qBittorrent sees
|
||||
docker exec qbittorrent curl -s https://ipinfo.io/ip
|
||||
```
|
||||
|
||||
This should show your VPN server's IP, not your VPS IP.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Gluetun Won't Connect
|
||||
|
||||
**Check logs:**
|
||||
```bash
|
||||
docker logs gluetun
|
||||
```
|
||||
|
||||
**Common causes:**
|
||||
- Wrong credentials
|
||||
- Unsupported server location
|
||||
- Provider API issues
|
||||
|
||||
**Solutions:**
|
||||
1. Verify credentials are correct
|
||||
2. Try different server countries
|
||||
3. Check provider status page
|
||||
|
||||
#### qBittorrent Can't Access Internet
|
||||
|
||||
**Symptoms:**
|
||||
- Can't download torrents
|
||||
- Can't access trackers
|
||||
|
||||
**Check:**
|
||||
```bash
|
||||
# Test internet connectivity through Gluetun
|
||||
docker exec qbittorrent curl -s https://google.com
|
||||
```
|
||||
|
||||
**Solutions:**
|
||||
1. Restart Gluetun: `docker restart gluetun`
|
||||
2. Check VPN server status
|
||||
3. Try different server location
|
||||
|
||||
#### Services Start But No VPN Protection
|
||||
|
||||
**Check network mode:**
|
||||
```bash
|
||||
docker inspect qbittorrent | grep -i network
|
||||
```
|
||||
|
||||
Should show: `"NetworkMode": "service:gluetun"`
|
||||
|
||||
**Fix:**
|
||||
1. Ensure `vpn_enabled: true` in configuration
|
||||
2. Redeploy: `ansible-playbook -i inventory/hosts site.yml`
|
||||
|
||||
### Debug Commands
|
||||
|
||||
```bash
|
||||
# Check all container status
|
||||
docker ps
|
||||
|
||||
# Check Gluetun detailed logs
|
||||
docker logs gluetun --tail 50
|
||||
|
||||
# Check qBittorrent logs
|
||||
docker logs qbittorrent --tail 50
|
||||
|
||||
# Test VPN connection
|
||||
docker exec gluetun wget -qO- https://ipinfo.io/ip
|
||||
|
||||
# Check qBittorrent network
|
||||
docker exec qbittorrent ip route
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Custom VPN Servers
|
||||
|
||||
Some providers allow specifying exact servers:
|
||||
|
||||
```yaml
|
||||
# For providers that support server selection
|
||||
vpn_server_hostnames: "nl123.nordvpn.com,de456.nordvpn.com"
|
||||
```
|
||||
|
||||
### Port Forwarding
|
||||
|
||||
For providers that support port forwarding (like PIA):
|
||||
|
||||
```yaml
|
||||
# Enable port forwarding (if supported by provider)
|
||||
vpn_port_forwarding: true
|
||||
```
|
||||
|
||||
### Kill Switch
|
||||
|
||||
Gluetun includes a built-in kill switch that blocks all traffic if VPN disconnects. This is enabled by default.
|
||||
|
||||
### Custom DNS
|
||||
|
||||
```yaml
|
||||
# Use custom DNS servers through VPN
|
||||
vpn_dns_servers: "1.1.1.1,1.0.0.1"
|
||||
```
|
||||
|
||||
### Multiple VPN Servers
|
||||
|
||||
```yaml
|
||||
# Connect to multiple countries (load balanced)
|
||||
vpn_countries: "Netherlands,Germany,Switzerland,Romania"
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### 1. Use Strong Credentials
|
||||
|
||||
- Generate unique passwords for VPN services
|
||||
- Store credentials securely
|
||||
- Rotate credentials periodically
|
||||
|
||||
### 2. Choose Privacy-Friendly Locations
|
||||
|
||||
**Good choices:**
|
||||
- Netherlands, Germany, Switzerland (strong privacy laws)
|
||||
- Romania, Moldova (good for torrenting)
|
||||
|
||||
**Avoid:**
|
||||
- Countries with data retention laws
|
||||
- Your home country (for maximum privacy)
|
||||
|
||||
### 3. Monitor Connection Status
|
||||
|
||||
Set up monitoring to alert if VPN disconnects:
|
||||
|
||||
```bash
|
||||
# Add to crontab for monitoring
|
||||
*/5 * * * * docker exec gluetun wget -qO- https://ipinfo.io/ip | grep -v "YOUR_VPS_IP" || echo "VPN DOWN" | mail -s "VPN Alert" your@email.com
|
||||
```
|
||||
|
||||
### 4. Regular Testing
|
||||
|
||||
- Test IP changes monthly
|
||||
- Verify no DNS leaks
|
||||
- Check for WebRTC leaks
|
||||
|
||||
### 5. Enhanced Security Features
|
||||
|
||||
The VPN configuration includes several security enhancements:
|
||||
|
||||
**Kill Switch Protection:**
|
||||
- Firewall automatically blocks traffic if VPN disconnects
|
||||
- No data leaks even during VPN reconnection
|
||||
- Configured automatically with `FIREWALL=on`
|
||||
|
||||
**DNS Leak Prevention:**
|
||||
- Custom DNS servers prevent ISP DNS leaks
|
||||
- DNS over TLS disabled to avoid conflicts
|
||||
- Malicious domain blocking enabled
|
||||
|
||||
**Network Isolation:**
|
||||
- Download clients isolated from other services
|
||||
- Only necessary ports exposed through VPN
|
||||
- Outbound traffic restricted to Docker subnet
|
||||
|
||||
**Port Configuration:**
|
||||
- qBittorrent: Port 8080 (through VPN)
|
||||
- SABnzbd: Port 8081 (through VPN, if enabled)
|
||||
- Automatic port conflict resolution
|
||||
|
||||
## Provider Comparison
|
||||
|
||||
| Provider | OpenVPN | WireGuard | Port Forward | P2P Friendly | Notes |
|
||||
|----------|---------|-----------|--------------|--------------|-------|
|
||||
| NordVPN | ✅ | ❌ | ❌ | ✅ | Good speeds, many servers |
|
||||
| ExpressVPN | ✅ | ❌ | ❌ | ✅ | Premium service, fast |
|
||||
| Surfshark | ✅ | ✅ | ❌ | ✅ | Good value, unlimited devices |
|
||||
| PIA | ✅ | ✅ | ✅ | ✅ | Port forwarding support |
|
||||
| CyberGhost | ✅ | ❌ | ❌ | ✅ | Dedicated P2P servers |
|
||||
| ProtonVPN | ✅ | ✅ | ❌ | ✅* | *Plus plan required for P2P |
|
||||
| Mullvad | ✅ | ✅ | ✅ | ✅ | Privacy-focused, anonymous |
|
||||
| Windscribe | ✅ | ❌ | ❌ | ✅ | Good free tier |
|
||||
|
||||
## Getting Help
|
||||
|
||||
### Provider Support
|
||||
|
||||
Most VPN providers have specific guides for Docker/Gluetun:
|
||||
- Check your provider's knowledge base
|
||||
- Search for "Docker" or "Gluetun" setup guides
|
||||
- Contact provider support for OpenVPN credentials
|
||||
|
||||
### Community Resources
|
||||
|
||||
- [Gluetun Wiki](https://github.com/qdm12/gluetun-wiki) - Comprehensive provider list
|
||||
- [r/VPN](https://reddit.com/r/VPN) - General VPN discussions
|
||||
- [r/selfhosted](https://reddit.com/r/selfhosted) - Self-hosting community
|
||||
|
||||
### Troubleshooting Checklist
|
||||
|
||||
1. ✅ VPN subscription active?
|
||||
2. ✅ Correct provider name in config?
|
||||
3. ✅ Valid credentials?
|
||||
4. ✅ Supported server location?
|
||||
5. ✅ Provider allows P2P traffic?
|
||||
6. ✅ Gluetun container running?
|
||||
7. ✅ qBittorrent using Gluetun network?
|
||||
8. ✅ No firewall blocking VPN?
|
||||
|
||||
Remember: VPN configuration can be tricky. Start with a simple setup and gradually add complexity as needed.
|
||||
Reference in New Issue
Block a user