Docker Networking Solution - Portable Media Stack
TL;DR: Removed custom networks with hardcoded subnets. Now uses default Docker bridge networking for universal compatibility across Linux/macOS/Windows without subnet conflicts.
Problem Analysis ✅ SOLVED
Your original docker-compose.yml defined custom networks with hardcoded subnets that conflicted with Docker Desktop extensions:
# ❌ PROBLEMATIC (Original)
networks:
media_network:
name: usenet_media_network
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16 # CONFLICT!
sharing_network:
name: usenet_sharing_network
driver: bridge
ipam:
config:
- subnet: 172.21.0.0/16 # CONFLICT!Docker Desktop Extension Conflicts Detected:
172.17.0.0/16- Default bridge network172.19.0.0/16- Portainer extension172.20.0.0/16- VS Code installer extension ← YOUR CONFLICT172.22.0.0/16- AI tools extension
Modern Portable Solution ✅ IMPLEMENTED
1. Removed All Custom Networks
# ✅ SOLUTION: No networks section = uses default bridge
# NO hardcoded subnets
# NO extension conflicts
# NO cross-platform issues2. Why This Works Better
For Media Automation Stacks, Custom Networks Provide ZERO Benefits:
| Requirement | Default Bridge | Custom Networks |
|---|---|---|
| Service Discovery | ✅ Container names work | ✅ Container names work |
| Inter-service Communication | ✅ All services can reach each other | ✅ All services can reach each other |
| Port Publishing | ✅ Works identically | ✅ Works identically |
| DNS Resolution | ✅ Automatic | ✅ Automatic |
| Resource Isolation | ✅ Process isolation | ✅ Process isolation |
| Cross-platform Compatibility | ✅ Universal | ❌ Conflicts |
| Docker Desktop Extensions | ✅ No conflicts | ❌ Subnet conflicts |
| Maintenance | ✅ Zero config | ❌ Subnet management |
3. Inter-Service Communication Examples
All your services communicate the same way as before:
# Sonarr connects to SABnzbd
SABNZBD_HOST: sabnzbd
SABNZBD_PORT: 8080
# Radarr connects to SABnzbd
SABNZBD_HOST: sabnzbd
SABNZBD_PORT: 8080
# Bazarr connects to Sonarr/Radarr
SONARR_HOST: sonarr
SONARR_PORT: 8989
RADARR_HOST: radarr
RADARR_PORT: 7878Container names work identically on default bridge network.
Modern Docker Compose Best Practices
1. Network Architecture Principles
# ✅ MODERN APPROACH
services:
sonarr:
# NO networks: section
# Uses default bridge automatically
# Container name 'sonarr' is DNS resolvable
radarr:
# NO networks: section
# Can reach sonarr via 'sonarr:8989'
sabnzbd:
# NO networks: section
# All *arr services reach via 'sabnzbd:8080'2. When You SHOULD Use Custom Networks
Custom networks are beneficial for:
- Complex multi-tier applications (web/app/db tiers)
- Strict security isolation (DMZ, internal services)
- External network integration (connecting to existing networks)
- Advanced routing requirements (multiple external interfaces)
Custom networks are NOT beneficial for:
- ✅ Media automation stacks (your use case)
- ✅ Development environments
- ✅ Single-host deployments
- ✅ Docker Desktop usage
3. Cross-Platform Compatibility
| Platform | Default Bridge | Custom Networks |
|---|---|---|
| Linux Docker | ✅ Always works | ⚠️ May conflict with host networks |
| macOS Docker Desktop | ✅ Always works | ⚠️ May conflict with extensions |
| Windows Docker Desktop | ✅ Always works | ⚠️ May conflict with extensions |
| Docker Swarm | ✅ Works with overlay | ⚠️ Requires careful network design |
CLI Command Reliability
Before (Custom Networks)
# ❌ Unreliable - subnet conflicts cause failures
docker compose up # "Pool overlaps" errors
usenet --start # Network creation failures
usenet --stop # Inconsistent behaviorAfter (Default Bridge)
# ✅ Reliable - no network conflicts possible
docker compose up # Always works
usenet --start # Always works
usenet --stop # Always worksFiles Modified ✅
1. Main Configuration Fixed
- File:
docker-compose.yml - Change: Removed all
networks:sections from services and networks definition - Result: Uses default bridge network automatically
2. Portable Reference Created
- File:
docker-compose.portable.yml - Purpose: Clean reference implementation with core services
- Usage: Copy-paste template for new environments
Testing Results ✅
# ✅ Configuration Valid
$ docker compose config --services
transmission
sabnzbd
radarr
sonarr
bazarr
# ... (all 20 services listed)
# ✅ Dry Run Successful
$ docker compose up --dry-run
DRY-RUN MODE - Network usenet_default Creating
DRY-RUN MODE - Network usenet_default Created
# ... (all containers create successfully)Recommended Workflow
1. Immediate Use
# Your existing compose file now works without conflicts
cd /home/joe/usenet
docker compose up -d
# All services accessible at usual ports:
# http://localhost:8989 (Sonarr)
# http://localhost:7878 (Radarr)
# http://localhost:8080 (SABnzbd)
# http://localhost:32400 (Plex)2. Agent-Friendly CLI
# These commands now work reliably
./usenet --start # Starts all services
./usenet --stop # Stops all services
./usenet status # Shows service health3. Development/Testing
# Use portable version for clean testing
docker compose -f docker-compose.portable.yml up -dNetwork Security Notes
Q: Is removing custom networks less secure?
A: No security difference for your use case.
- Process Isolation: Identical (Docker's core security model)
- Port Access: Identical (services only accessible via published ports)
- Host Access: Identical (containers cannot access host by default)
- Inter-container: Identical (containers can reach each other via names)
Custom networks provide network-level isolation, which is irrelevant when:
- All services need to communicate with each other (your media stack)
- All services are trusted (your own applications)
- External access is controlled via published ports (your setup)
Long-term Maintainability
✅ Benefits of Default Bridge Approach
- Zero network configuration to maintain
- No subnet planning required
- Universal compatibility across Docker environments
- Immune to Docker Desktop extension conflicts
- Simpler troubleshooting (fewer moving parts)
- Better documentation (standard Docker patterns)
❌ Problems Solved
- ❌ No more "Pool overlaps with other one on this address space" errors
- ❌ No more Docker Desktop extension conflicts
- ❌ No more cross-platform networking issues
- ❌ No more subnet management overhead
- ❌ No more agent CLI networking failures
Advanced Troubleshooting Guide
Common Network Issues and Solutions
1. Service Discovery Problems
# ❌ Problem: "curl: (6) Could not resolve host: sonarr"
# ✅ Solution: Check container names and ensure services are running
# Verify all containers are running
docker compose ps
# Test DNS resolution between containers
docker compose exec radarr nslookup sonarr
docker compose exec sonarr ping -c 3 sabnzbd
# Expected: Container names resolve to internal Docker IPs (172.17.x.x range)2. Port Binding Conflicts
# ❌ Problem: "Error starting userland proxy: listen tcp 0.0.0.0:8080: bind: address already in use"
# ✅ Solution: Find and stop conflicting services
# Find what's using the port
sudo netstat -tulpn | grep :8080
# or
sudo lsof -i :8080
# Change port mapping if needed (doesn't affect inter-service communication)
ports:
- "8081:8080" # External:Internal - internal stays 8080 for service discovery3. Docker Desktop Extension Conflicts (Legacy)
# ❌ Problem: "Pool overlaps with other one on this address space"
# ✅ Solution: Already solved - no custom networks = no conflicts
# If you still see this error, you may have old custom networks:
docker network ls | grep usenet
docker network prune # Remove unused networks4. Cross-Platform DNS Resolution Issues
# ❌ Problem: Services can't find each other on Windows/macOS
# ✅ Solution: Use container names (works identically across platforms)
# Inside any container, this works on all platforms:
curl http://sonarr:8989/api/v3/system/status
curl http://radarr:7878/api/v3/system/status
curl http://sabnzbd:8080/api?mode=versionNetwork Debugging Commands
Container Network Inspection
# View network configuration for all services
docker compose ps --format "table {{.Name}}\t{{.Ports}}"
# Inspect specific container network settings
docker inspect <container_name> | grep -A 20 '"NetworkSettings"'
# View default bridge network details
docker network inspect bridgeInter-Service Communication Testing
# Test communication between services (inside containers)
docker compose exec sonarr wget -qO- http://sabnzbd:8080/api?mode=version
docker compose exec radarr curl -s http://prowlarr:9696/api/v1/system/status
docker compose exec plex ping -c 1 sonarr
# Test from host to services
curl http://localhost:8989/api/v3/system/status # Sonarr
curl http://localhost:7878/api/v3/system/status # RadarrPerformance Optimization
Network Performance Best Practices
# Monitor network usage between containers
docker stats --format "table {{.Container}}\t{{.NetIO}}"
# For high-throughput scenarios (large file transfers), consider:
# 1. Host networking for specific services (loses container isolation)
# 2. Optimized Docker daemon settings
# 3. SSD storage for Docker root directoryMemory and Connection Limits
# Optimize for large media libraries
services:
sonarr:
deploy:
resources:
limits:
memory: 1G # Increase if you have >10k episodes
environment:
- "DOCKER_MODS=linuxserver/mods:universal-tshoot" # For debuggingModern Docker Compose Networking Reference
When to Use Custom Networks (2024 Update)
| Use Case | Default Bridge | Custom Bridge | Overlay Networks |
|---|---|---|---|
| Single-host media stack | ✅ Recommended | ❌ Unnecessary | ❌ Overkill |
| Multi-host deployment | ❌ Single host only | ❌ Single host only | ✅ Required |
| Microservices with isolation | ❌ All services communicate | ✅ Recommended | ✅ Recommended |
| Development environments | ✅ Recommended | ❌ Maintenance overhead | ❌ Unnecessary |
| Production single-node | ✅ Recommended | ⚠️ Only if security requires | ⚠️ Only if scaling planned |
Network Security Model Comparison
# DEFAULT BRIDGE (Current implementation)
# ✅ Process isolation via Docker
# ✅ Port-based access control
# ✅ No network-level restrictions between containers
# ✅ Simplest security model - appropriate for trusted services
# CUSTOM BRIDGE (Previous implementation)
# ✅ Process isolation via Docker
# ✅ Port-based access control
# ✅ Network-level isolation (can restrict container communication)
# ❌ Subnet management complexity
# ❌ Cross-platform compatibility issues
# OVERLAY NETWORKS (Multi-host)
# ✅ Process isolation via Docker
# ✅ Port-based access control
# ✅ Network-level isolation + encryption
# ✅ Multi-host service discovery
# ❌ Complex setup and troubleshootingContainer Communication Patterns
Service-to-Service API Calls
# Pattern: http://<container_name>:<internal_port>/<path>
# Works identically on default bridge and custom networks
# Examples used by *arr services:
SONARR_URL: "http://sonarr:8989"
RADARR_URL: "http://radarr:7878"
PROWLARR_URL: "http://prowlarr:9696"
SABNZBD_URL: "http://sabnzbd:8080"Database Connections (if added)
# If you add a database service later:
postgres:
image: postgres:15
container_name: media-db
environment:
POSTGRES_DB: media
sonarr:
environment:
# Connect to database using container name
- "ConnectionStrings__Main=Server=media-db;Database=sonarr;..."Monitoring and Observability
Network Metrics Collection
# Add to your monitoring stack for network insights:
# 1. Netdata (already included) - shows container network I/O
# 2. Docker stats - real-time container metrics
# 3. Container logs - application-level network errors
# View real-time network usage
watch "docker stats --no-stream --format 'table {{.Container}}\t{{.NetIO}}'"Log Analysis for Network Issues
# Check for common network errors in container logs
docker compose logs | grep -i "connection refused\|timeout\|network\|dns"
# Service-specific network debugging
docker compose logs sonarr | grep -i "sabnzbd\|download"
docker compose logs radarr | grep -i "download\|indexer"Future-Proofing Your Network Architecture
Scaling Considerations
Adding More Services
# New services automatically join default bridge
lidarr: # Music automation
image: lscr.io/linuxserver/lidarr:latest
container_name: lidarr
# No networks: section needed
# Automatically discovers sonarr, radarr, prowlarr, etc.Multi-Host Expansion (Docker Swarm)
# If you later need multi-host deployment:
docker swarm init
# Services automatically get overlay networks
# Container name discovery works across hostsMigration Strategies
From Custom Networks (Historical)
# If migrating from old custom network setup:
1. Backup configuration: ./usenet --backup create
2. Stop services: docker compose down
3. Remove custom networks: docker network prune
4. Update compose file (remove networks sections)
5. Start services: docker compose up -d
# No application configuration changes neededTo External Network Integration
# If you later need to connect to external networks:
networks:
default: # Still use default for internal communication
external: false
external_network: # Connect specific services to external networks
external: true
name: company_network
services:
overseerr: # Example: expose only request interface externally
networks:
- default # Talk to other services
- external_network # Accept external requestsSummary: Your media automation stack now uses modern Docker networking best practices with universal compatibility and zero maintenance overhead. This foundation scales from single-node deployment to enterprise multi-host orchestration without architectural changes.
Remote Access with Tailscale
Why Tailscale (Configured: 2025-12-29)
Problem: ISP (Live Oak Fiber) rotates external IPs aggressively, breaking Plex remote access and any port-forwarding-based solutions.
Solution: Tailscale provides a stable mesh VPN with fixed IP addresses regardless of ISP changes.
How Tailscale Works
┌─────────────────────────────────────────────────────────────┐
│ Tailscale Network │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Media Server │◄───────►│ Phone/Laptop │ │
│ │ 100.x.x.x │ │ 100.y.y.y │ │
│ │ (Bazzite) │ WireGuard│ (Any device) │ │
│ └──────────────┘ tunnel └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│ ISP #1 │ │ ISP #2 │
│ Dynamic │ │ Different│
│ IP │ │ Network │
└──────────┘ └──────────┘Key Benefits:
- Stable IPs: Each device gets a fixed
100.x.x.xaddress - Zero port forwarding: No router configuration needed
- ISP-agnostic: Works across any network (home, mobile, coffee shop)
- Encrypted: WireGuard end-to-end encryption
- More secure than port forwarding: No exposed services to the internet
Current Configuration
| Device | Tailscale IP | Purpose |
|---|---|---|
| Media Server (Bazzite) | 100.115.21.9 | Hosts all services |
| Additional devices | Join network via tailscale up | Access services |
Accessing Services via Tailscale
Once connected to your Tailscale network, access all services using the Tailscale IP:
# From any Tailscale-connected device:
http://100.115.21.9:8989 # Sonarr
http://100.115.21.9:7878 # Radarr
http://100.115.21.9:8080 # SABnzbd
http://100.115.21.9:32400 # Plex
http://100.115.21.9:9696 # Prowlarr
http://100.115.21.9:8265 # TdarrPlex Configuration for Tailscale
In Plex Settings → Network:
- Custom server access URLs: Add
http://100.115.21.9:32400 - LAN Networks: Add
100.64.0.0/10(Tailscale CGNAT range) - Secure connections: Set to "Preferred" (Tailscale handles encryption)
- Remote access: Can disable port forwarding entirely if using Tailscale exclusively
Security Model
Tailscale vs Port Forwarding:
| Aspect | Port Forwarding | Tailscale |
|---|---|---|
| Attack surface | Exposed to internet | Only Tailscale network |
| Authentication | Service-level only | Network-level + service |
| IP exposure | Public IP visible | Private 100.x.x.x only |
| Brute force risk | High (internet-facing) | Low (must join network first) |
| ISP dependency | Requires static IP or DDNS | None |
Best Practice: Keep services bound to localhost or Tailscale IP only. No need to expose ports publicly.
Adding New Devices
# On any device you want to connect:
# 1. Install Tailscale
# 2. Authenticate with same account
tailscale up
# Device automatically joins your network and can access servicesTroubleshooting
# Check Tailscale status
tailscale status
# Verify connectivity to media server
ping 100.115.21.9
# Check if services are reachable
curl -s http://100.115.21.9:8989/api/v3/system/status # Sonarr