Features Pricing Docs FAQ Get Started

Installation Guide

Step-by-step instructions to install SparkBox on a UGREEN NAS, VPS, or any server with Docker.

Prerequisites

For VPS

  • Server running Ubuntu 22.04+ or Debian 12+
    • Minimum: 2GB RAM, 1 vCPU, 20GB disk
    • Recommended: 4-8GB RAM, 2-4 vCPU
  • Root or sudo access
  • SSH client (Terminal on Mac/Linux, PuTTY or Windows Terminal on Windows)
  • Domain name (optional -- not needed if using Tailscale)
  • VPN subscription (only if enabling the Media Center module)

For NAS

  • UGREEN NASync NAS (DXP2800, DXP4800, or similar Docker-capable model)
  • 4GB+ RAM (8GB recommended, 16GB for media + Immich)
  • SSH access enabled on the NAS
  • VPN subscription (only if enabling the Media Center module)

Windows / WSL2: SparkBox also works on Windows via WSL2 (Windows Subsystem for Linux). This is community-supported and not officially tested. Install Ubuntu from the Microsoft Store, then follow the VPS installation steps inside WSL2.

VPS Installation

Step 1: Connect to Your Server

bash
ssh root@YOUR_SERVER_IP

If your provider set up a non-root user:

bash
ssh youruser@YOUR_SERVER_IP
sudo -i    # Switch to root

Step 2: Update Your System

bash
apt update && apt upgrade -y

Step 3: Run the Installer

Quick Install (Recommended)

bash
curl -sSL https://get.sparkbox.app/install.sh | sudo bash

This automatically:

  1. Installs Docker and required system packages
  2. Downloads SparkBox to /opt/sparkbox
  3. Configures the firewall (ports 22, 80, 443, 51820/udp)
  4. Launches the setup wizard

Manual Install

bash
# Install Docker
curl -fsSL https://get.docker.com | sh

# Clone the repository
git clone https://github.com/tomsparkreview/sparkbox /opt/sparkbox
cd /opt/sparkbox

# Install dashboard dependencies
cd dashboard && npm install --production && cd ..

# Make the CLI executable and link it
chmod +x sparkbox
ln -sf /opt/sparkbox/sparkbox /usr/local/bin/sparkbox

# Run the setup wizard
sudo sparkbox install

Step 4: Setup Wizard

The wizard launches automatically after installation. See the Setup Wizard section below for details.

VPS Provider Recommendation

SparkBox runs on any VPS. We recommend Hostinger for the best balance of price, performance, and reliability. Other popular options:

ProviderMinimum PlanNotes
HostingerKVM 1 (4GB, 2 vCPU) ~$5/moRecommended -- fast, affordable, global locations
HetznerCX22 (4GB, 2 vCPU) ~$5/moBest value, EU + US locations
DigitalOceanBasic 4GB ~$24/moSimple, reliable
VultrCloud Compute 4GB ~$24/moGlobal locations
ContaboVPS S 8GB ~$7/moBudget option, more RAM

UGREEN NAS (DXP2800, DXP4800, etc.)

Before installing SparkBox on a UGREEN NAS, complete the privacy lockdown steps in the NAS Guide. This disables telemetry, blocks phone-home connections, and secures your device.

Step 1: Enable SSH

  1. Open the UGOS web interface in your browser
  2. Go to Control Panel > Terminal
  3. Check "Enable SSH Service"
  4. Leave port on 22
  5. Click Apply
  6. Restart the NAS -- SSH does not start listening until after a reboot

Step 2: Connect via SSH

Use PuTTY, not Windows' built-in SSH client. Windows' ssh command in PowerShell/Command Prompt often fails with "Permission denied" when VPN adapters (NordVPN, Surfshark, etc.) are installed. Download PuTTY from putty.org (single .exe, no install needed).

PuTTY settings:

  • Host: Your NAS IP (e.g., 192.168.1.17)
  • Port: 22
  • Click Open
  • Log in with your UGOS admin username and password

On Mac/Linux, the regular terminal SSH client works fine:

bash
ssh your-admin-username@192.168.1.17

Step 3: Install Docker (if not already installed)

UGREEN NAS typically comes with Docker pre-installed. Verify:

bash
docker --version
docker compose version

If Docker is missing:

bash
curl -fsSL https://get.docker.com | sh

Step 4: Install SparkBox

bash
sudo git clone https://github.com/tomsparkreview/sparkbox /opt/sparkbox
cd /opt/sparkbox
sudo chmod +x sparkbox
sudo ./sparkbox install

Note on UGREEN: The installer detects NAS environments and skips UFW firewall configuration (UGOS has its own firewall, plus you should have a router-level block per the NAS Guide). It also adjusts default ports to avoid conflicts with UGOS services.

Step 5: Handle Port Conflicts

UGOS uses several ports that conflict with SparkBox defaults:

PortUsed BySparkBox DefaultResolution
80UGOS web UINginx Proxy Manager HTTPSparkBox uses 8080 on NAS
443UGOS web UINginx Proxy Manager HTTPSSparkBox uses 8443 on NAS
53dnsmasq (UGOS)Pi-hole DNSDisable dnsmasq: sudo systemctl disable dnsmasq
5000/5001UGOS managementNot usedNo conflict

The installer handles port remapping automatically on detected NAS environments. See the Port Conflict Resolution section in the NAS Guide for manual port configuration.

Setup Wizard

The setup wizard runs automatically after installation. Here is what each step configures:

Server Address

Enter your server's IP address or domain name.

  • No domain? Use your server's IP (e.g., 203.0.113.42 for VPS, 192.168.1.17 for NAS)
  • Have a domain? Enter it (e.g., myserver.example.com)

Timezone

Enter your timezone in Continent/City format:

RegionTimezone
US EasternAmerica/New_York
US CentralAmerica/Chicago
US PacificAmerica/Los_Angeles
UKEurope/London
Central EuropeEurope/Berlin
JapanAsia/Tokyo
AustraliaAustralia/Sydney

Module Selection

After choosing a profile, you can toggle individual modules on or off. Use arrow keys to navigate, space to toggle, Enter to confirm.

VPN Credentials (Media Profile)

If you selected Media or Full profile, enter your VPN provider and credentials. See the VPN Provider Setup section in the Media Guide for step-by-step credential extraction for each provider.

Dashboard Password

Set a password for the SparkBox web dashboard. Leave blank to auto-generate one (saved to the credentials file).

Module Configuration

Depending on your selections:

  • Privacy enabled: Set a Pi-hole admin password (or auto-generate)
  • VPN Access enabled: Set a WireGuard web UI password (or auto-generate)
  • Cloud enabled: Database passwords are auto-generated

Deploy

Say Yes to deploy immediately. SparkBox pulls container images and starts your services. This takes 2-10 minutes depending on internet speed and how many modules you enabled.

Profile Selection

Privacy Profile

Best for: VPS users focused on security and ad-blocking.

Modules enabled: Core, Dashboard, Privacy (Pi-hole + Vaultwarden + Authelia), Monitoring (Uptime Kuma), VPN Access (WireGuard)

Total RAM: ~750MB idle

Media Profile

Best for: Home server or NAS users building a private streaming platform.

Modules enabled: Core, Dashboard, Media Center (Gluetun + qBittorrent + Prowlarr + Sonarr + Radarr + Bazarr + Jellyfin + Seerr)

Total RAM: ~2.5GB idle

Requires: A VPN subscription (Surfshark, NordVPN, ProtonVPN, Mullvad, AirVPN, etc.)

Full Profile

Best for: Servers with 8GB+ RAM that want everything.

Modules enabled: All Privacy + Media modules, plus Cloud (Nextcloud), Paperless-ngx, File Browser, Monitoring, and more.

Total RAM: ~5-6GB idle

Custom Profile

Pick exactly what you want from the module catalog. Start with Core + Dashboard, add modules one at a time.

Post-Install

Accessing the Dashboard

Once deployment completes, open your browser:

url
http://YOUR_SERVER_IP:8443

Log in with the password you set during installation.

Finding Auto-Generated Credentials

If passwords were auto-generated during setup:

bash
cat /opt/sparkbox/state/initial-credentials.txt

Save these passwords somewhere safe (e.g., Vaultwarden), then delete the file:

bash
rm /opt/sparkbox/state/initial-credentials.txt

Verify All Services

bash
sparkbox status

All enabled services should show as running. If any service is stopped, check its logs:

bash
sparkbox logs sb-SERVICE_NAME

Post-Install Checklist

  • Open the dashboard at http://YOUR_SERVER:8443 and verify login works
  • Change the NPM default password (open http://YOUR_SERVER:81, login: admin@example.com / changeme)
  • Save your auto-generated credentials, then delete initial-credentials.txt
  • If using Privacy: set your router or device DNS to your server's IP for ad-blocking
  • If using Privacy: open Vaultwarden, create your account, install the Bitwarden browser extension
  • If using Media: add your VPN credentials, configure Prowlarr indexers (see Prowlarr)
  • If using Cloud: complete Nextcloud first-run wizard, set up domain + SSL first
  • If using WireGuard: create client configs and scan QR codes on your devices
  • If using Monitoring: add service monitors in Uptime Kuma, set up notifications
  • Set up a domain for SSL (see below) or enable Tailscale for remote access
  • Create your first backup: sparkbox backup

Domain Setup with Nginx Proxy Manager

A domain lets you access services via URLs like vault.yourdomain.com instead of remembering port numbers. It also provides HTTPS encryption and is required for Nextcloud mobile apps.

Step 1: Get a Domain

Register a domain from any registrar (Cloudflare, Namecheap, Porkbun, etc.). Cost: ~$10/year.

Step 2: Create DNS Records

In your registrar's DNS settings, create an A record:

dns
Type:  A
Name:  * (wildcard)
Value: YOUR_SERVER_IP
TTL:   300 (or Auto)

Step 3: Configure Nginx Proxy Manager

  1. Open NPM at http://YOUR_SERVER:81
  2. Default login: admin@example.com / changeme
  3. Change the default password immediately
  4. Click Proxy Hosts > Add Proxy Host
  5. For each service:
    • Domain Names: vault.yourdomain.com
    • Forward Hostname / IP: sb-vaultwarden (the container name)
    • Forward Port: 80 (the container's internal port)
    • SSL tab: Request a new SSL certificate, check "Force SSL", agree to Let's Encrypt ToS

Suggested Subdomains

ServiceSubdomainContainerForward Port
Dashboarddash.yourdomain.comsb-dashboard8443
Pi-holepihole.yourdomain.comsb-pihole80
Vaultwardenvault.yourdomain.comsb-vaultwarden80
Nextcloudcloud.yourdomain.comsb-nextcloud443
Jellyfinwatch.yourdomain.comsb-jellyfin-media8096
Seerrrequest.yourdomain.comsb-seerr5055
Bazarrsubs.yourdomain.comsb-bazarr6767
Uptime Kumastatus.yourdomain.comsb-uptime-kuma3001
WireGuardvpn.yourdomain.comsb-wg-easy51821
File Browserfiles.yourdomain.comsb-filebrowser80

Note: VPN-routed services (qBittorrent, Sonarr, Radarr, Prowlarr) are not on the sb_proxy network because they share Gluetun's network namespace. To proxy them through NPM, use your server's LAN IP or host.docker.internal as the hostname with the host-mapped port.

Remote Access

Option 1: Tailscale (Recommended)

Tailscale is the easiest way to access SparkBox from anywhere. It creates a secure mesh VPN using WireGuard under the hood, with zero configuration.

Enable the Tailscale Module

bash
sparkbox enable tailscale

Get an Auth Key

  1. Go to https://login.tailscale.com/admin/settings/keys
  2. Create a new auth key (reusable is recommended)
  3. Copy the key

Configure and Start

bash
# Add to /opt/sparkbox/.env
TS_AUTHKEY=tskey-auth-xxxxx
bash
sparkbox up

All your services are now accessible at your Tailscale IP (e.g., http://100.x.x.x:8443 for the dashboard).

Tailscale on a NAS with Internet Blocked

If you followed the NAS privacy lockdown (blocking internet at the router):

  1. Temporarily disable the router firewall rule blocking the NAS
  2. Install and authenticate Tailscale
  3. Re-enable the router firewall rule

After initial authentication, Tailscale tunnels directly between devices -- the NAS does not need internet access to maintain the connection.

Option 2: WireGuard VPN (Self-Hosted)

Enable the VPN Module

bash
sparkbox enable vpn
sparkbox up

Create a Client

  1. Open wg-easy at http://YOUR_SERVER:51821
  2. Log in with your WireGuard password
  3. Click New Client and give it a name (e.g., "My Phone")
  4. Click the QR code icon

Connect

  1. Install the WireGuard app on your phone (iOS / Android)
  2. Tap Add Tunnel > Scan QR Code
  3. Scan the QR code from wg-easy
  4. Connect

Firewall note: Port 51820/UDP must be open. The installer configures this automatically on VPS. On NAS, you may need to forward this port on your router.

Option 3: Domain + Nginx Proxy Manager

For public-facing servers. See Domain Setup above.

CLI Quick Reference

bash
sparkbox status           # See what's running
sparkbox up               # Start all enabled modules
sparkbox down             # Stop everything
sparkbox restart          # Restart all services
sparkbox restart privacy  # Restart just one module
sparkbox update           # Pull latest images
sparkbox logs sb-NAME     # View service logs
sparkbox modules          # List all modules
sparkbox enable cloud     # Enable a module
sparkbox disable files    # Disable a module
sparkbox backup           # Create a backup
sparkbox restore FILE     # Restore from backup
sparkbox urls             # Show all service URLs
sparkbox help             # Full command list

Updating

Update All Services

bash
sparkbox update

This pulls the latest Docker images and recreates all containers. Your data and configuration are preserved.

Update a Specific Module

bash
sparkbox update privacy

Update SparkBox Itself

bash
cd /opt/sparkbox && git pull && sparkbox update

Backups

Create a Backup

bash
sparkbox backup

Or from the dashboard: Settings > Backups > Create Backup Now

Restore from Backup

bash
sparkbox restore /opt/sparkbox/backups/sparkbox-backup-TIMESTAMP.tar.gz

Backups include your configuration, module settings, and service data. Backups are automatically encrypted with AES-256-GCM when SB_BACKUP_KEY is set (done automatically during installation).

Note: Media files (movies, TV shows, music) are NOT included in backups due to size. Back those up separately.

Uninstalling

bash
sparkbox down
rm -rf /opt/sparkbox
rm -f /usr/local/bin/sparkbox

This stops all containers and removes SparkBox. Docker remains installed.

Troubleshooting

Solutions for common issues across all SparkBox modules, organized by category.

Gluetun VPN Issues

Gluetun Is Unhealthy / Won't Connect

Symptoms: sb-gluetun shows "unhealthy" in sparkbox status or the dashboard. Media services that depend on Gluetun are also down.

Check logs:

bash
sparkbox logs sb-gluetun

Common causes and fixes:

  1. Wrong VPN credentials -- This is the most common cause. VPN service credentials are NOT your login email/password.
    bash
    # Edit your credentials
    nano /opt/sparkbox/.env
    # Fix VPN_PROVIDER, WIREGUARD_PRIVATE_KEY, etc.
    sparkbox restart media
    Where to find credentials:
  2. VPN subscription expired -- Verify your subscription is active with your provider.
  3. Corrupted Gluetun state -- Reset Gluetun's local data:
    bash
    sparkbox down
    rm -rf /opt/sparkbox/modules/media/config/gluetun
    sparkbox up
  4. Server country unavailable -- Try a different country:
    bash
    # Edit .env
    SERVER_COUNTRIES=Netherlands
    sparkbox restart media
  5. NAS internet blocked -- If you blocked internet at the router (per NAS Guide), you need a firewall exception for the VPN port. See Firewall and VPN Coexistence.

VPN Connected but Wrong Country

bash
# Check current VPN location
docker exec sb-gluetun wget -qO- ipinfo.io

# Change country in .env
nano /opt/sparkbox/.env
# Change SERVER_COUNTRIES=United States to your preferred country
sparkbox restart media

VPN Connected but No Internet Through Tunnel

Symptoms: Gluetun shows "healthy" but qBittorrent cannot download and Prowlarr cannot reach indexers.

bash
# Test internet connectivity from inside Gluetun
docker exec sb-gluetun wget -qO- --timeout=10 ifconfig.me

# If that fails, check DNS
docker exec sb-gluetun nslookup google.com

Fixes:

  • Restart the media module: sparkbox restart media
  • Check if your VPN provider is having an outage
  • Try a different server country

qBittorrent Issues

Can't Log In to qBittorrent

qBittorrent generates a temporary password every time it starts.

bash
docker logs sb-qbittorrent 2>&1 | grep "temporary password"

Default username is admin. After logging in, set a permanent password in Tools > Options > Web UI.

qBittorrent Can't Connect / No Downloads

  1. Check Gluetun is healthy:
    bash
    docker ps --format "table {{.Names}}\t{{.Status}}" | grep gluetun
    If Gluetun is unhealthy, fix it first (see above).
  2. Verify VPN tunneling:
    bash
    docker exec sb-gluetun wget -qO- ifconfig.me
  3. Check network interface: In qBittorrent, go to Tools > Options > Advanced > Network Interface -- it should be tun0.

Downloads Are Slow

  • VPN server too far away: Change SERVER_COUNTRIES in .env to a closer country, then sparkbox restart media
  • Not enough seeders: Check the torrent in qBittorrent -- if it shows 0 seeds, try an alternative release in Radarr/Sonarr
  • VPN throttling: Some VPN providers throttle torrents. Try a different server or provider

Arr App Issues (Radarr, Sonarr, Prowlarr)

"Root Folder Does Not Exist" in Radarr/Sonarr

The /data directory structure has not been created.

bash
sudo mkdir -p /data/{torrents/{movies,tv,music},media/{movies,tv,music}}
sudo chown -R $(id -u):$(id -g) /data
sudo chmod -R 775 /data

Verify the root folder paths:

  • Radarr: /data/media/movies
  • Sonarr: /data/media/tv
  • Lidarr: /data/media/music

Downloads Stuck at "Importing" or "Waiting to Import"

This is almost always a permissions issue.

bash
sudo chown -R $(id -u):$(id -g) /data
sudo chmod -R 775 /data

Also verify PUID/PGID in .env matches your user:

bash
id
# Compare uid/gid with PUID/PGID in /opt/sparkbox/.env

No Indexers in Radarr/Sonarr

Indexers are managed by Prowlarr and synced automatically.

  1. Open Prowlarr at http://YOUR_SERVER:8181
  2. Verify you have indexers added under Indexers
  3. Check Settings > Apps -- Radarr and Sonarr should be listed
  4. Click Sync App Indexers to force a sync
  5. Verify the API keys match between Prowlarr and Radarr/Sonarr

Services Can't Connect to Each Other

Do NOT use localhost when connecting services together across Docker containers. Use internal Docker IPs instead. See the Docker Networking reference in the Media Guide.

Jellyfin Issues

Empty Library After Downloads Finish

  1. Check library paths: Jellyfin libraries should point to:
    • Movies: /data/media/movies
    • TV Shows: /data/media/tv
    • Music: /data/media/music
  2. Force a library scan: Go to Dashboard > Libraries > click ... > Scan Library
  3. Check if files exist:
    bash
    ls -la /data/media/movies/
    ls -la /data/media/tv/

No Hardware Transcoding

Symptoms: Playback is slow or stuttering. Dashboard shows software transcoding (no "(HW)" indicator).

  1. Check /dev/dri exists:
    bash
    ls -la /dev/dri/
  2. Verify device mapping: The Jellyfin container must have /dev/dri:/dev/dri mapped.
  3. Verify Jellyfin settings: Dashboard > Playback > Transcoding > Hardware acceleration: VAAPI, VA-API Device: /dev/dri/renderD128

See Hardware Transcoding in the NAS Guide for full setup.

Jellyfin App Can't Connect

  • On LAN: Use http://YOUR_SERVER_IP:8096
  • Remote via Tailscale: Use http://YOUR_TAILSCALE_IP:8096
  • With domain: Use https://watch.yourdomain.com
  • Check Jellyfin is running: sparkbox status

Port Conflicts

Finding What Uses a Port

bash
# Show all listening ports
sudo ss -tlnp

# Check if a specific port is in use
sudo ss -tlnp | grep :80

Common Port Conflicts on NAS

PortCommonly Used BySparkBox ServiceFix
80NAS web UI (UGOS)Nginx Proxy ManagerSet HTTP_PORT=8080 in .env
443NAS web UI (HTTPS)Nginx Proxy ManagerSet HTTPS_PORT=8443 in .env
53NAS DNS (dnsmasq)Pi-holeDisable dnsmasq
5055Various system servicesSeerrChange Seerr port in docker-compose.yml

Changing SparkBox Ports

bash
nano /opt/sparkbox/.env
# Change the relevant port variable
sparkbox restart

Permission Issues

PUID/PGID Mismatch

Symptoms: "Permission denied" errors in logs, files created with wrong ownership, imports failing.

bash
# Find your user/group ID
id

# Check what's in .env
grep -E "PUID|PGID" /opt/sparkbox/.env

# Fix ownership
sudo chown -R 1000:1000 /data
sudo chown -R 1000:1000 /opt/sparkbox

# Restart
sparkbox restart

Docker Socket Permission Denied

bash
# Add your user to the docker group (preferred)
sudo usermod -aG docker your-username
# Log out and back in for the change to take effect

NAS-Specific Issues

SSH Won't Connect (UGREEN)

  1. Verify SSH is enabled: UGOS web UI > Control Panel > Terminal > "Enable SSH Service" must be checked
  2. Restart the NAS: SSH may not start listening until after a reboot
  3. Use PuTTY, not Windows SSH: Windows' built-in SSH client fails when VPN adapters are installed. Download PuTTY
  4. Check SSH auto-disable: UGOS may auto-disable SSH after a timeout or firmware update
  5. Check the IP address: Make sure you are using the correct NAS IP from your router's DHCP client list

Firewall Blocking Services (UGREEN)

Skip the UGOS built-in firewall. In testing, it blocks SSH and Docker ports even when LAN traffic is explicitly allowed. Use router-level firewall rules instead.

Docker Not Working After NAS Firmware Update

bash
# Check Docker is running
sudo systemctl status docker

# If stopped, start it
sudo systemctl start docker
sudo systemctl enable docker

# Check SparkBox services
sparkbox status

# If services are down, bring them up
sparkbox up

Also check: SSH is still enabled (may be reset by firmware update), dnsmasq is still disabled.

NAS Internet Block Breaking Docker Pulls

If you blocked internet at the router and need to pull Docker images:

  1. Temporarily disable the router firewall rule blocking the NAS
  2. Pull your images: sparkbox update or docker compose pull
  3. Re-enable the router firewall rule

Dashboard Issues

Can't Log In to Dashboard

  1. Check the dashboard is running:
    bash
    sparkbox status | grep dashboard
  2. Forgot password -- reset it:
    bash
    nano /opt/sparkbox/.env
    # Find SB_ADMIN_PASSWORD_HASH= and delete the value (leave it blank)
    sparkbox restart dashboard
    This triggers the first-run password setup on next login.
  3. Browser cache issue: Try incognito/private browsing mode or clear your browser cache.

Disk Space Issues

Disk Filling Up

bash
df -h
du -sh /data/torrents/*
du -sh /data/media/*

Common causes:

  • qBittorrent keeping completed torrents: Enable auto-removal in Radarr/Sonarr > Settings > Download Clients > enable Remove Completed
  • Hardlinks not working (double disk usage): Both torrents/ and media/ must be on the same volume. See Check Hardlinks.
  • Docker images accumulating:
    bash
    docker image prune -a

How to Check VPN Is Working

bash
# Get VPN IP (should NOT be your real IP)
docker exec sb-gluetun wget -qO- ifconfig.me

# Get your real IP (for comparison)
curl -s ifconfig.me

If both IPs are the same, the VPN is NOT working. Check Gluetun logs.

Full Verification

bash
# Check VPN IP and location
docker exec sb-gluetun wget -qO- ipinfo.io

# Verify qBittorrent is tunneled (should match VPN IP)
docker exec sb-qbittorrent wget -qO- ifconfig.me

# Check Gluetun health status
docker inspect --format '{{.State.Health.Status}}' sb-gluetun

Continuous Monitoring

bash
bash /opt/sparkbox/modules/media/test-media.sh

Step 1: Verify Same Filesystem

bash
df /data/torrents /data/media

Both must show the same device. If they show different devices, hardlinks will NOT work.

Step 2: Check Filesystem Type

bash
df -T /data

Hardlinks work on: ext4, btrfs, xfs, zfs. Hardlinks do NOT work on: exFAT, ntfs-3g, fat32, network shares (NFS/SMB).

Step 3: Test Hardlink Creation

bash
# Create a test file
touch /data/torrents/hardlink_test

# Create a hardlink
ln /data/torrents/hardlink_test /data/media/hardlink_test

# Verify -- inode numbers should match
ls -i /data/torrents/hardlink_test
ls -i /data/media/hardlink_test

# Clean up
rm /data/torrents/hardlink_test /data/media/hardlink_test

General Troubleshooting Steps

When something is not working and you are not sure where to start:

bash
# 1. Check status
sparkbox status

# 2. Check logs for the failing service
sparkbox logs sb-SERVICE_NAME

# 3. Restart the module
sparkbox restart MODULE_NAME

# 4. Restart everything
sparkbox down
sparkbox up

# 5. Check system resources
free -h       # RAM
df -h         # Disk
top -bn1 | head -5   # CPU

NAS Guide

Everything you need to run SparkBox on a UGREEN NAS -- privacy lockdown, hardware transcoding, port conflicts, storage paths, and performance expectations.

Privacy Lockdown (Before Installing SparkBox)

Do this BEFORE installing SparkBox on a UGREEN NAS. UGOS Pro ships with telemetry enabled, cloud relay connections to Hong Kong, and DNS services that phone home. Lock it down first.

Why This Matters

UGREEN NAS devices (DXP2800, DXP4800, etc.) have several privacy concerns:

  • Telemetry enabled by default -- tracks page visits, click behavior, IP address, device ID
  • UGREENlink routes through Hong Kong -- relay servers transmit your device serial, hashed email, and device location
  • Phones home even with remote access disabled -- DNS lookups to Chinese domains persist
  • No disk encryption -- UGOS Pro has zero encryption at rest
  • Known CVEs -- command injection, buffer overflow vulnerabilities published Dec 2025

Step-by-Step Lockdown

1. Disable Telemetry

Control Panel > Service > About > Device analysis tab

  • Uncheck "Help UGREEN NAS improve its products and services"
  • Click Apply

2. Disable WebFind

Same area -- uncheck "Enable WebFind". This unregisters your NAS from find.ugnas.com.

3. Disable UGREENlink

Control Panel > Remote Access

  • Uncheck "UGREENlink remote access"
  • Click Apply

After this, the UGREEN mobile and PC apps stop working outside your home network. They still work on LAN.

4. Handle Your UGREEN Cloud Account

Recommended: Leave the account bound but cut off access. Do NOT unbind the device -- UGREEN warns that unbinding removes all data. The account becomes useless once the firewall blocks internet in the next step.

5. Block the NAS from the Internet (Router Level)

This is the most important step. Block at your router so the NAS cannot bypass the block regardless of what UGOS does.

UniFi (Recommended):

  1. Go to Settings > Security > Traffic & Firewall Rules
  2. Create a new rule:
    • Name: Block NAS Internet
    • Action: Block
    • Source: Your NAS IP address (e.g., 192.168.1.17)
    • Destination: Internet
    • Schedule: Always
  3. Save and apply

Pi-hole / AdGuard Home (domain-level blocking): If you want Docker to still pull images but block UGREEN domains:

blocklist
*.ugnas.com
*.ug.link
*.ugreen.com
*.baidu.com
*.crashlytics.com
*.firebase.google.com

Skip the UGOS built-in firewall. In testing, it causes issues with SSH access even when LAN traffic is allowed. The router-level block is more reliable.

6. Enable SSH

Control Panel > Terminal -- Check "Enable SSH Service", leave port on 22, click Apply, then restart the NAS.

7. Kill dnsmasq

bash
sudo systemctl stop dnsmasq
sudo systemctl disable dnsmasq

This disables a built-in DNS service used for UGREENlink routing. It conflicts with Pi-hole on port 53.

8. Verify Lockdown

bash
sudo ss -tunp | grep -v '192.168'

You should only see 127.0.0.1 connections. If no external IPs appear, you are locked down.

9. Re-Login on Mobile App

After disabling UGREENlink, add the device again by IP address in the UGREEN NAS app. This connects directly over local WiFi instead of through UGREEN's servers.

What Changes After Lockdown

BeforeAfter
PC/mobile app works everywhereWorks on LAN only (use Tailscale for remote)
Updates happen automaticallyDownload firmware manually, upload via web UI
Docker images pull freelyTemporarily disable firewall rule, pull images, re-enable

Optional: Encrypt Sensitive Data

Since UGOS Pro has no disk encryption, protect sensitive files with:

  • Cryptomator -- encrypt files/folders before they reach the NAS
  • VeraCrypt -- encrypted containers
  • LUKS -- Linux-native encryption via SSH (advanced)

Firewall and VPN Coexistence

If you blocked your NAS from the internet at the router level AND want to use Gluetun VPN for media downloads, you need a targeted exception.

The Problem

Gluetun needs to reach your VPN provider's servers on the internet. If the NAS is fully blocked, the VPN tunnel cannot establish.

The Solution: UniFi Exception for VPN Port

Create a second firewall rule that allows ONLY the VPN traffic through:

  1. In UniFi, go to Settings > Security > Traffic & Firewall Rules
  2. Create a new rule above the "Block NAS Internet" rule:
    • Name: Allow NAS VPN
    • Action: Allow
    • Source: Your NAS IP
    • Destination: Internet
    • Protocol: UDP
    • Port: 51820 (WireGuard) or 1194 (OpenVPN)

Order matters. The allow rule must be above the block rule. Rules are processed top-to-bottom.

Immich ML Model Downloads

The Immich ML container downloads machine learning models (~500MB) on first startup. If your NAS is firewalled, temporarily disable the block, start SparkBox, wait for models to download, then re-enable the block.

bash
ls ${SB_ROOT}/modules/immich/config/model-cache/

Tailscale and the Firewall

Tailscale needs internet access for initial authentication only. After that, it works peer-to-peer. Temporarily disable the block, authenticate, then re-enable. If Tailscale loses connection, create an allow rule for UDP port 41641.

/dev/net/tun Device

Both Gluetun and Tailscale require /dev/net/tun. If the container fails to start with a tun error:

bash
# Check if the TUN device exists
ls -la /dev/net/tun

# If it doesn't exist, load the kernel module
sudo modprobe tun

# Make it persist across reboots
echo "tun" | sudo tee /etc/modules-load.d/tun.conf

Hardware Transcoding

Intel Quick Sync hardware transcoding allows Jellyfin to transcode 4K HEVC video without heavy CPU usage. This is essential on a NAS.

Supported Devices

DeviceCPUQuick SyncTranscoding Capability
UGREEN DXP2800Intel N100Yes4K HEVC 8/10-bit, VP9, AV1 decode, multiple streams
UGREEN DXP4800Intel N100YesSame as above

Setup: Mapping /dev/dri into Containers

Step 1: Verify /dev/dri Exists

bash
ls -la /dev/dri/

Step 2: Set Permissions

bash
sudo usermod -aG render your-username
sudo usermod -aG video your-username

Step 3: Enable in SparkBox

SparkBox's Jellyfin module automatically detects /dev/dri and maps it. If transcoding is not working, verify the device mapping in the module's docker-compose.yml:

yaml
devices:
  - /dev/dri:/dev/dri

Step 4: Configure Jellyfin

  1. Open Jellyfin at http://YOUR_NAS_IP:8096
  2. Go to Dashboard > Playback > Transcoding
  3. Set Hardware acceleration to Video Acceleration API (VAAPI)
  4. Set VA-API Device to /dev/dri/renderD128
  5. Enable: H.264, HEVC, VP9, AV1 decode; H.264, HEVC encode
  6. Click Save

Performance: Intel N100 Transcoding

  • 4K HEVC HDR (8-bit and 10-bit) -- smooth
  • Multiple simultaneous 4K transcodes -- handles 2-3 concurrent streams
  • Dolby TrueHD + Atmos passthrough -- confirmed
  • AV1 hardware decode -- supported on N100 (12th gen+)

Port Conflict Resolution

UGREEN (UGOS Pro)

PortUGOS Uses ForSparkBox ServiceSolution
80UGOS web UI (HTTP)Nginx Proxy ManagerChange HTTP_PORT to 8080 in .env
443UGOS web UI (HTTPS)Nginx Proxy ManagerChange HTTPS_PORT to 8443 in .env
53dnsmasqPi-hole DNSDisable dnsmasq
9000UGOS PortainerSparkBox PortainerChange PORTAINER_PORT to 9001
5000/5001UGOS managementNot usedNo conflict
bash
# Example: change Nginx Proxy Manager ports
HTTP_PORT=8080
HTTPS_PORT=8443

How to Find Port Conflicts

bash
sudo ss -tlnp
sudo ss -tlnp | grep :80
sudo ss -tlnp | grep :443
sudo ss -tlnp | grep :53

PUID / PGID Setup

Finding Your PUID/PGID

bash
id
# Example: uid=1000(kevin) gid=1000(kevin)

Setting PUID/PGID in SparkBox

Edit /opt/sparkbox/.env:

env
PUID=1000
PGID=1000

Common NAS User IDs

NASDefault Admin UserTypical PUIDTypical PGID
UGREENYour admin account10001000

Storage Paths on a NAS

Recommended Directory Structure

text
/volume1/                          # Main data volume
├── docker/
│   └── sparkbox/                  # SparkBox config
└── data/
    ├── torrents/
    │   ├── movies/
    │   ├── tv/
    │   └── music/
    └── media/
        ├── movies/
        ├── tv/
        └── music/

Why This Structure Matters (Hardlinks)

Both torrents/ and media/ MUST be on the same filesystem/volume. When Radarr/Sonarr imports a download, they create hardlinks -- the file appears in both locations but only uses disk space once. If the directories are on different volumes, hardlinks fail and files are copied instead (using double the disk space).

bash
df /data/torrents /data/media
# Both should show the same filesystem/device

Creating the Folder Structure

bash
sudo mkdir -p /volume1/data/{torrents/{movies,tv,music},media/{movies,tv,music}}
sudo chown -R $(id -u):$(id -g) /volume1/data
sudo chmod -R 775 /volume1/data

Performance Expectations

UGREEN DXP2800 (Intel N100, 8GB RAM)

WorkloadCPU UsageRAM UsageNotes
Privacy profile only5-10% idle~1GBRuns effortlessly
Media profile only10-15% idle~2.5GBComfortable, leaves 5GB free
Full profile15-25% idle~5-6GBTight on 8GB, works but no room for extras
Jellyfin 4K transcode (1 stream)20-30%+200MBHardware transcode, barely noticed
Jellyfin 4K transcode (3 streams)40-60%+500MBStill handles it via Quick Sync
Immich ML processing80-100%+1.5GBCPU spikes during photo import, settles after

Recommendations by RAM

RAMWhat You Can Run
4GBPrivacy profile only. No media stack.
8GBPrivacy + Media, OR Privacy + a few productivity apps. Not everything at once.
16GBFull profile comfortably. Everything at once.

Upgrade Path

The DXP2800 has 1 DDR5 SODIMM slot (upgradeable). Replace the 8GB SODIMM with 16GB or 32GB DDR5 -- UGOS detects the new RAM automatically.

Disk I/O Considerations

  • SATA drives (HDD): Fine for media storage and streaming. Slow for database-heavy apps
  • M.2 NVMe SSD: Ideal for Docker containers and databases
  • RAID 1 (mirrored): Recommended for data protection

Tip: Put SparkBox's configuration and container data on the M.2 SSD, and media files on the SATA drives. Fast app performance with large, cheap storage for movies/TV.

Backing Up SparkBox on a NAS

Backup Strategy

  1. SparkBox config: Use sparkbox backup (automated, encrypted)
  2. Media files: Use your NAS's built-in backup tools (rsync, UGOS Backup)
  3. Off-site backup: Copy backups to an external USB drive or cloud storage (encrypted with Cryptomator)

Backing Up to a Different Volume

bash
mkdir -p /volume1/backups/sparkbox
ln -sfn /volume1/backups/sparkbox /opt/sparkbox/backups

What Is Backed Up

IncludedNOT Included
.env configurationMedia files (movies, TV, music)
Module settingsDocker images (re-pulled on restore)
Container config volumesTemporary/cache files
Dashboard settingsLogs
Backup encryption key

Additional NAS Tips

  • SSH Auto-Disable: UGOS may auto-disable SSH after a timeout or firmware update. Re-enable it in Control Panel > Terminal
  • After firmware updates: Verify SSH is enabled, dnsmasq is disabled, and SparkBox services are running
  • VLAN Isolation (Advanced): For maximum security, put the NAS on its own VLAN with firewall rules allowing only LAN device access to NAS services

Media Guide

Complete setup guide for the Media Center module -- VPN configuration, the /data directory structure, hardlinks, and step-by-step configuration for every media service.

VPN Provider Setup

The Media Center module routes all download traffic through a commercial VPN via Gluetun. You MUST have an active VPN subscription.

Important: VPN credentials are NOT your login email/password. You need service credentials from your provider's manual setup or API section.

Surfshark

Surfshark offers the best value for long-term plans with fast WireGuard speeds.

  1. Go to my.surfshark.com/vpn/manual-setup/main
  2. Select WireGuard
  3. Generate or copy your credentials (private key + address)
env
VPN_PROVIDER=surfshark
VPN_TYPE=wireguard
WIREGUARD_PRIVATE_KEY=your_private_key_here
WIREGUARD_ADDRESSES=10.14.0.2/16
SERVER_COUNTRIES=United States

NordVPN

  1. Go to NordVPN Manual Configuration
  2. Select NordLynx (WireGuard)
  3. Generate a private key
env
VPN_PROVIDER=nordvpn
VPN_TYPE=wireguard
WIREGUARD_PRIVATE_KEY=your_private_key_here
WIREGUARD_ADDRESSES=10.5.0.2/16
SERVER_COUNTRIES=United States

ProtonVPN

ProtonVPN supports port forwarding, which can improve upload speeds and seeding.

env
VPN_PROVIDER=protonvpn
VPN_TYPE=wireguard
WIREGUARD_PRIVATE_KEY=your_private_key_here
WIREGUARD_ADDRESSES=10.2.0.2/32
SERVER_COUNTRIES=United States
VPN_PORT_FORWARDING=on

AirVPN

env
VPN_PROVIDER=airvpn
VPN_TYPE=wireguard
WIREGUARD_PRIVATE_KEY=your_private_key_here
WIREGUARD_PUBLIC_KEY=server_public_key_here
WIREGUARD_PRESHARED_KEY=your_preshared_key_here
WIREGUARD_ADDRESSES=your_assigned_ip/32
FIREWALL_VPN_INPUT_PORTS=your_forwarded_port
VPN_PORT_FORWARDING=on

Mullvad

env
VPN_PROVIDER=mullvad
VPN_TYPE=wireguard
WIREGUARD_PRIVATE_KEY=your_private_key_here
WIREGUARD_ADDRESSES=your_assigned_ip/32
SERVER_COUNTRIES=United States

Other Providers

Gluetun supports 30+ providers. See the full provider list for configuration details.

Applying VPN Credentials

bash
sparkbox restart media

# Verify VPN is working
docker exec sb-gluetun wget -qO- ifconfig.me   # VPN IP
curl -s ifconfig.me                              # Real IP (should differ)

The /data Directory Structure

text
/data/
├── torrents/          # qBittorrent downloads here
│   ├── movies/
│   ├── tv/
│   └── music/
└── media/             # Radarr/Sonarr organize here (Jellyfin reads from here)
    ├── movies/
    ├── tv/
    └── music/

Creating the Structure

bash
sudo mkdir -p /data/{torrents/{movies,tv,music},media/{movies,tv,music}}
sudo chown -R $(id -u):$(id -g) /data
sudo chmod -R 775 /data

On a NAS, replace /data with your volume path (e.g., /volume1/data).

Why Hardlinks Matter

When qBittorrent finishes downloading a movie, Radarr needs to move it to the media folder. There are two approaches:

  • Copy -- duplicates the file. A 20GB movie uses 40GB of disk space
  • Hardlink -- creates a second reference to the same data. The 20GB movie appears in both locations but uses only 20GB total

Hardlinks only work when both directories are on the same filesystem/drive.

Internal Docker Networking

Services sharing Gluetun's network (reach each other via localhost)

ServiceAddressPort
qBittorrentlocalhost8080
Prowlarrlocalhost9696
Sonarrlocalhost8989
Radarrlocalhost7878
Lidarrlocalhost8686
FlareSolverrlocalhost8191

Services on the bridge network

ServiceContainer NamePort
Bazarrsb-bazarr6767
Jellyfinsb-jellyfin-media8096
Seerrsb-seerr5055

Common Connection Reference

FromToHostPort
RadarrqBittorrentlocalhost8080
SonarrqBittorrentlocalhost8080
ProwlarrRadarrhttp://localhost:7878
ProwlarrSonarrhttp://localhost:8989
SeerrJellyfinsb-jellyfin-media8096
SeerrRadarrsb-gluetun7878
SeerrSonarrsb-gluetun8989
BazarrRadarrsb-gluetun7878
BazarrSonarrsb-gluetun8989

Configuring Prowlarr (Indexers)

Prowlarr manages your indexers and syncs them to Radarr, Sonarr, and Lidarr automatically.

Open Prowlarr: http://YOUR_SERVER:8181

Step 1: Add Indexers

  1. Go to Indexers > Add Indexer
  2. Add your preferred indexers. Recommended public indexers: 1337x, The Pirate Bay, LimeTorrents, EZTV (TV), YTS (movies)
  3. Test each indexer after adding

Tip: The more indexers you add, the more results you get. If you only have one or two, you will miss many releases.

Step 2: Set Up FlareSolverr

Some indexers use Cloudflare protection. FlareSolverr bypasses this.

  1. Go to Settings > Indexers
  2. Click + to add a new proxy
  3. Select FlareSolverr
  4. Host: http://localhost:8191
  5. Tag: Create a tag like flaresolverr
  6. Add the same tag to any indexer blocked by Cloudflare

Step 3: Connect to Radarr and Sonarr

  1. Go to Settings > Apps
  2. Add Radarr:
    • Prowlarr Server: http://localhost:9696
    • Radarr Server: http://localhost:7878
    • API Key: Copy from Radarr's Settings > General > API Key
  3. Add Sonarr:
    • Prowlarr Server: http://localhost:9696
    • Sonarr Server: http://localhost:8989
    • API Key: Copy from Sonarr's Settings > General > API Key
  4. Click Sync App Indexers

Configuring Radarr (Movies)

Open Radarr: http://YOUR_SERVER:7878

Step 1: Add Download Client

  1. Go to Settings > Download Clients > + > qBittorrent
  2. Host: localhost, Port: 8080, Username: admin, Category: movies
  3. Test and Save

Step 2: Set Root Folder

Settings > Media Management > Add Root Folder: /data/media/movies

Step 3: Configure Media Management

  • Enable Rename Movies
  • Enable Use Hardlinks instead of Copy -- this is critical

Step 4: Set Quality Profile

Strategy: grab 1080p quickly, then auto-upgrade to 4K if available.

  1. Go to Settings > Profiles
  2. Uncheck everything below 1080p
  3. Set Cutoff to Bluray-1080p
  4. Set Upgrade Until to Bluray-2160p Remux

Step 5: Add Movies

Go to Movies > Add New, search, select quality profile and root folder, click Add Movie.

Configuring Sonarr (TV Shows)

Open Sonarr: http://YOUR_SERVER:8989

Sonarr works the same as Radarr but for TV shows.

Step 1: Add Download Client

Same as Radarr: Host localhost, Port 8080, Category tv

Step 2: Set Root Folder

Path: /data/media/tv

Step 3: Configure Media Management

  • Enable Rename Episodes
  • Enable Use Hardlinks instead of Copy

Step 4: Add TV Shows

Go to Series > Add New, search, select profile, root folder, and which seasons to monitor.

Configuring qBittorrent

Open qBittorrent: http://YOUR_SERVER:8080

Getting the Temporary Password

bash
docker logs sb-qbittorrent 2>&1 | grep "temporary password"

Default username is admin.

Step 1: Set a Permanent Password

Go to Tools > Options > Web UI and set a permanent username and password.

Step 2: Configure Categories and Save Paths

CategorySave Path
movies/data/torrents/movies
tv/data/torrents/tv
music/data/torrents/music

Step 3: Important Settings

  • Advanced > Network Interface: should be tun0 (the VPN tunnel)
  • BitTorrent > Seeding Limits: Set per your preference
  • Downloads > Default Save Path: /data/torrents

Configuring Jellyfin

Open Jellyfin: http://YOUR_SERVER:8096

Step 1: Complete First-Run Wizard

Create an admin account and set your preferred language.

Step 2: Add Media Libraries

Library TypeFolder Path
Movies/data/media/movies
Shows/data/media/tv
Music/data/media/music

Step 3: Configure Hardware Transcoding

If your server has Intel Quick Sync, set Hardware acceleration to VAAPI and VA-API Device to /dev/dri/renderD128. See Hardware Transcoding for detailed setup.

Step 4: Install Client Apps

Jellyfin apps are available for Roku, Fire TV, Apple TV, Android TV, Samsung TV, LG TV, iOS, Android, and all desktop browsers. Enter your server address during app setup.

Configuring Seerr (Requests)

Open Seerr: http://YOUR_SERVER:5055

Step 1: Connect to Jellyfin

On the first-run wizard, select Jellyfin. URL: http://sb-jellyfin-media:8096. Sign in with your Jellyfin admin credentials.

Step 2: Connect to Radarr

Settings > Services > Radarr. Hostname: sb-gluetun, Port: 7878, API Key from Radarr.

Step 3: Connect to Sonarr

Settings > Services > Sonarr. Hostname: sb-gluetun, Port: 8989, API Key from Sonarr.

Step 4: Create User Accounts

Import users from Jellyfin or create local accounts. Set permissions for what they can request and auto-approve.

Configuring Bazarr (Subtitles)

Open Bazarr: http://YOUR_SERVER:6767

Step 1: Connect to Radarr & Sonarr

Settings > Radarr/Sonarr. Host: sb-gluetun, Port: 7878 (Radarr) or 8989 (Sonarr), API Key from each.

Step 2: Add Subtitle Providers

Recommended providers:

  • OpenSubtitles.com -- the largest subtitle database (free account required)
  • Subscene -- good for non-English content
  • Addic7ed -- popular for TV shows

Step 3: Configure Languages

Add your preferred subtitle languages and set language profiles for movies and TV shows.

Configuring Lidarr (Music)

Open Lidarr: http://YOUR_SERVER:8686

Lidarr works the same as Radarr/Sonarr but for music. Download client: localhost:8080, Category: music, Root folder: /data/media/music.

For quality profiles, enable FLAC, MP3-320, MP3-256 with cutoff set to FLAC (prefer lossless).

Family Sharing

Share your media server with family and friends without exposing admin interfaces. They only see Jellyfin (to watch) and Seerr (to request).

Using Tailscale (Recommended)

  1. Invite family to your tailnet: In the Tailscale admin console, click Share on your SparkBox machine and enter their email
  2. They install Tailscale on their device and accept your invite
  3. Give them two links:
    text
    http://100.x.x.x:5055    # Seerr (request movies and shows)
    http://100.x.x.x:8096    # Jellyfin (watch everything)
  4. Set up Jellyfin app on their TV: Install the Jellyfin app and enter your Tailscale IP as the server address

What NOT to Share

  • Radarr, Sonarr, Prowlarr -- admin tools
  • qBittorrent -- the torrent client
  • SparkBox Dashboard -- full admin access
  • Pi-hole, Vaultwarden, Authelia -- personal privacy tools

Using Tailscale Funnel (No Account Needed)

If you do not want family members to create Tailscale accounts:

bash
tailscale funnel 8096

This creates a public HTTPS URL anyone can access. Set strong passwords and consider Authelia in front of it.

The test-media.sh Script

bash
bash /opt/sparkbox/modules/media/test-media.sh

What It Checks

CheckWhat It Verifies
DockerDocker is installed and running
Configuration.env exists and VPN credentials are set
Folder Structure/data directories exist with correct permissions
ContainersAll expected containers are running and healthy
VPN ConnectionGluetun is connected, VPN IP differs from real IP
VPN TunnelingqBittorrent and Prowlarr traffic routes through VPN
Web UI AccessEach service's web UI responds on its expected port
Hard Linkstorrents/ and media/ are on the same filesystem

Interpreting Results

text
=========================================
  Passed: 18   Failed: 0   Warnings: 2
=========================================
  • PASS -- check succeeded, everything is working
  • FAIL -- something is broken, follow the "Fix:" instructions
  • WARN -- not critical but should be investigated