13 min read

Building a Self-Hosted Streaming Service: FileBrowser + Jellyfin

Complete guide to setting up FileBrowser and Jellyfin together for a powerful self-hosted media streaming platform with advanced file management

Self-HostedMedia ServerJellyfinFileBrowserDockerStreaming

Building a Self-Hosted Streaming Service: FileBrowser + Jellyfin

Want your own Netflix-like streaming service with full control over your media library? By combining Jellyfin (media server) with FileBrowser (file management), you get a powerful self-hosted solution that rivals commercial streaming platforms.

This guide shows you how to set up both tools together for seamless media management and streaming.

What Are These Tools?

Jellyfin: The Free Media System

Jellyfin is an open-source media server that lets you:

  • Stream movies, TV shows, music, and photos to any device
  • Organize your library with metadata, posters, and descriptions
  • Transcode on-the-fly for different devices and bandwidths
  • Share with family/friends with user accounts and permissions
  • Access remotely via web, mobile apps (iOS/Android), or smart TVs

Think: Netflix, but you own everything.

FileBrowser: Web-Based File Management

FileBrowser provides a web interface to manage files:

  • Upload/download files via drag-and-drop
  • Create/delete/rename files and folders
  • Share files with temporary links
  • Edit files with built-in text editor
  • User management with permissions and quotas
  • Command execution for custom scripts

Think: Dropbox meets FTP, but self-hosted.

Why Use Them Together?

Separately, they're great. Together, they're transformative:

ChallengeSolution
Adding mediaUpload via FileBrowser, automatically appears in Jellyfin
Organizing filesRename/move files without SSH or FTP
Bulk uploadsDrag entire folders into FileBrowser
Remote managementManage library from phone/tablet
Sharing raw filesShare media files directly via FileBrowser links
No technical skills neededFamily members can add their own videos

The workflow:

  1. Upload movies to FileBrowser
  2. Organize into proper folders
  3. Jellyfin automatically scans and adds them
  4. Stream from any device

Architecture Overview

Here's how the components work together:

┌─────────────────────────────────────────────┐
│         Docker Host (Your Server)           │
│                                             │
│  ┌──────────────┐      ┌──────────────┐   │
│  │ FileBrowser  │      │  Jellyfin    │   │
│  │   :8080      │      │    :8096     │   │
│  └──────┬───────┘      └──────┬───────┘   │
│         │                      │            │
│         └──────┐      ┐────────┘           │
│                ▼      ▼                     │
│         ┌──────────────────┐               │
│         │  Shared Volume   │               │
│         │   /media         │               │
│         │   /movies        │               │
│         │   /tv-shows      │               │
│         │   /music         │               │
│         └──────────────────┘               │
└─────────────────────────────────────────────┘

Key concept: Both containers access the same media directory, so files added via FileBrowser are immediately available to Jellyfin.

Prerequisites

Before starting, ensure you have:

  • Linux server (Ubuntu, Debian, or similar)
  • Docker & Docker Compose installed
  • At least 2GB RAM (4GB+ recommended)
  • Storage space for your media (external drive recommended)
  • Basic command-line knowledge

Installation Guide

Step 1: Create Directory Structure

# Create project directory
mkdir -p ~/media-server
cd ~/media-server

# Create media directories
mkdir -p media/{movies,tv-shows,music,photos}

# Create config directories
mkdir -p config/{jellyfin,filebrowser}

Directory structure:

media-server/
├── media/
│   ├── movies/
│   ├── tv-shows/
│   ├── music/
│   └── photos/
├── config/
│   ├── jellyfin/
│   └── filebrowser/
└── docker-compose.yml

Step 2: Create Docker Compose File

Create docker-compose.yml:

version: '3.8'

services:
  # Jellyfin Media Server
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    restart: unless-stopped
    ports:
      - "8096:8096"  # HTTP web interface
      - "8920:8920"  # HTTPS (optional)
    volumes:
      - ./config/jellyfin:/config
      - ./config/jellyfin/cache:/cache
      - ./media:/media:ro  # Read-only for security
    environment:
      - PUID=1000  # Your user ID
      - PGID=1000  # Your group ID
      - TZ=America/New_York  # Your timezone
    devices:
      - /dev/dri:/dev/dri  # Hardware acceleration (optional)

  # FileBrowser File Management
  filebrowser:
    image: filebrowser/filebrowser:latest
    container_name: filebrowser
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - ./media:/srv  # Full access to media
      - ./config/filebrowser/filebrowser.db:/database.db
      - ./config/filebrowser/settings.json:/config/settings.json
    environment:
      - PUID=1000
      - PGID=1000

Step 3: Get Your User ID

# Find your user and group IDs
id

# Output example:
# uid=1000(your_user) gid=1000(your_group)

Update PUID and PGID in docker-compose.yml with your IDs.

Step 4: Start the Services

# Start containers
docker-compose up -d

# Verify they're running
docker-compose ps

# Check logs if needed
docker-compose logs -f

Initial Configuration

Configure FileBrowser

  1. Access FileBrowser: Open http://your-server-ip:8080

  2. Default credentials:

    • Username: admin
    • Password: admin
  3. Change password immediately:

    • Click on "Settings" (gear icon)
    • Go to "User Management"
    • Edit admin user
    • Set strong password
  4. Configure settings:

    • Go to "Settings" → "Global Settings"
    • Enable "Allow uploads"
    • Enable "Allow new files/folders"
    • Set default view to "List" or "Gallery"
  5. Create media folders (if not visible):

    • Navigate to root
    • You should see: movies/, tv-shows/, music/, photos/

Configure Jellyfin

  1. Access Jellyfin: Open http://your-server-ip:8096

  2. Initial setup wizard:

    • Select language
    • Create admin account (strong password!)
    • Click "Next"
  3. Add media libraries:

    For Movies:

    • Click "Add Media Library"
    • Content type: "Movies"
    • Display name: "Movies"
    • Folder: Click "+", add /media/movies
    • Click "OK"

    For TV Shows:

    • Add another library
    • Content type: "Shows"
    • Display name: "TV Shows"
    • Folder: /media/tv-shows

    For Music:

    • Content type: "Music"
    • Display name: "Music"
    • Folder: /media/music

    For Photos:

    • Content type: "Photos"
    • Display name: "Photos"
    • Folder: /media/photos
  4. Configure metadata:

    • Language: English (or your preference)
    • Country: United States (or your preference)
    • Enable "Download images"
    • Enable "Automatically refresh metadata"
  5. Finish setup and wait for initial library scan

File Naming Conventions

For Jellyfin to properly identify media, follow these naming patterns:

Movies

movies/
  ├── The Matrix (1999)/
  │   └── The Matrix (1999).mkv
  ├── Inception (2010)/
  │   └── Inception (2010).mp4
  └── Interstellar (2014)/
      └── Interstellar (2014).mkv

Pattern: Movie Title (Year)/Movie Title (Year).ext

TV Shows

tv-shows/
  ├── Breaking Bad/
  │   ├── Season 01/
  │   │   ├── Breaking Bad S01E01.mkv
  │   │   ├── Breaking Bad S01E02.mkv
  │   │   └── Breaking Bad S01E03.mkv
  │   └── Season 02/
  │       ├── Breaking Bad S02E01.mkv
  │       └── Breaking Bad S02E02.mkv
  └── Game of Thrones/
      └── Season 01/
          └── Game of Thrones S01E01.mkv

Pattern: Show Name/Season XX/Show Name SXXEXX.ext

Music

music/
  ├── Artist Name/
  │   ├── Album Name (Year)/
  │   │   ├── 01 - Track Name.mp3
  │   │   ├── 02 - Track Name.mp3
  │   │   └── cover.jpg
  │   └── Another Album (Year)/
  │       └── ...

The Workflow: Adding Media

Method 1: Upload via FileBrowser (Easiest)

  1. Open FileBrowser: http://your-server-ip:8080
  2. Navigate to appropriate folder (movies/, tv-shows/, etc.)
  3. Create folder for the movie/show (e.g., "The Matrix (1999)")
  4. Drag and drop your video file(s)
  5. Wait for upload to complete
  6. Rename if needed (right-click → Rename)

Method 2: Batch Upload via Command Line

# From your local machine
scp -r "Movie Collection/" user@server:~/media-server/media/movies/

# Or using rsync (better for large files)
rsync -avP "Movie Collection/" user@server:~/media-server/media/movies/

Method 3: Mount Network Share (Advanced)

Share your media folder via Samba/NFS, then add media directly from your desktop:

On server (install Samba):

sudo apt install samba
sudo nano /etc/samba/smb.conf

Add share:

[media]
path = /home/your_user/media-server/media
browseable = yes
writable = yes
guest ok = no
valid users = your_user

Restart Samba:

sudo systemctl restart smbd

On Windows: Connect to \\server-ip\media
On Mac: Connect to smb://server-ip/media

Automatic Library Updates

Configure Jellyfin to scan for new media automatically:

  1. Go to Jellyfin Dashboard
  2. Library → Select a library → "Edit"
  3. Enable "Monitor folder"
  4. Set scan interval (e.g., every 12 hours)
  5. Save

Alternatively, trigger manual scan:

  • Dashboard → "Scan All Libraries"

Or via API:

curl -X POST "http://localhost:8096/Library/Refresh" \
  -H "X-Emby-Token: YOUR_API_KEY"

User Management

Creating Users in FileBrowser

  1. Settings → "User Management"
  2. Click "New User"
  3. Set username/password
  4. Configure permissions:
    • Scope: /media/movies (limit access to specific folders)
    • Permissions: Upload, Create, Rename, Delete (as needed)
  5. Save

Use cases:

  • Family member who only adds movies
  • Friend who manages TV shows
  • Read-only user for viewing files

Creating Users in Jellyfin

  1. Dashboard → "Users"
  2. Click "+"
  3. Enter name
  4. Set password (or allow no password for trusted network)
  5. Configure access:
    • Enable/disable libraries per user
    • Set streaming quality limits
    • Allow/deny remote access
  6. Save

Advanced Configuration

Enable Hardware Transcoding (Jellyfin)

For faster transcoding and lower CPU usage:

  1. Dashboard → "Playback"
  2. Hardware acceleration: Select your GPU
    • Intel: "Intel QuickSync (QSV)"
    • NVIDIA: "NVIDIA NVENC"
    • AMD: "AMD AMF"
  3. Enable codecs: H264, HEVC, etc.
  4. Save

Note: Requires proper device mapping in docker-compose.yml (already included above).

Custom Commands in FileBrowser

Add useful commands for media management:

  1. Settings → "Command Runner"
  2. Add command:

Example: Convert video to H264

ffmpeg -i "$FILE" -c:v libx264 -crf 23 "${FILE%.mkv}_h264.mkv"

Example: Extract subtitles

ffmpeg -i "$FILE" -map 0:s:0 "${FILE%.mkv}.srt"
  1. Save and use via right-click → "Execute command"

Reverse Proxy (HTTPS)

Use Nginx or Caddy for secure access:

Caddy example:

jellyfin.yourdomain.com {
    reverse_proxy localhost:8096
}

files.yourdomain.com {
    reverse_proxy localhost:8080
}

Install Caddy and reload config:

sudo caddy reload

Now access via:

  • https://jellyfin.yourdomain.com
  • https://files.yourdomain.com

Remote Access

Option 1: Port forwarding

  • Forward ports 8096 and 8080 on your router
  • Access via http://your-public-ip:8096

Option 2: Cloudflare Tunnel (recommended)

  • Free, secure, no port forwarding
  • Works behind CGNAT
  • Built-in DDoS protection

Option 3: VPN (Tailscale/WireGuard)

  • Most secure
  • Access your network from anywhere
  • No exposed ports

Mobile Access

Jellyfin Apps

iOS:

  • Jellyfin Mobile (official, free)
  • Swiftfin (third-party, beautiful UI)

Android:

  • Jellyfin for Android (official, free)
  • Findroid (third-party, Material Design)

Download from:

  • App Store / Google Play
  • F-Droid (Android, open-source)

FileBrowser on Mobile

  • Use mobile browser: http://your-server-ip:8080
  • Responsive web interface works well on phones
  • Upload photos/videos from phone directly

Backup Strategy

What to backup:

  1. Jellyfin config: ./config/jellyfin/ (user settings, watched status)
  2. FileBrowser database: ./config/filebrowser/filebrowser.db (users, permissions)
  3. Media files: ./media/ (most important!)

Backup script:

#!/bin/bash
# backup-media-server.sh

BACKUP_DIR="/mnt/backup/media-server"
DATE=$(date +%Y%m%d_%H%M%S)

# Stop services
cd ~/media-server
docker-compose stop

# Backup configs
tar -czf "$BACKUP_DIR/config_$DATE.tar.gz" config/

# Backup media (or use rsync to external drive)
rsync -avP media/ /mnt/external-drive/media-backup/

# Start services
docker-compose start

echo "Backup completed: $DATE"

Automate with cron:

# Run every Sunday at 2 AM
0 2 * * 0 /home/user/backup-media-server.sh

Troubleshooting

Jellyfin not seeing new files

Check:

  1. File permissions: ls -la media/movies/
  2. Correct naming convention
  3. Trigger manual scan: Dashboard → "Scan All Libraries"
  4. Check logs: docker-compose logs jellyfin

Fix permissions:

sudo chown -R 1000:1000 media/
sudo chmod -R 755 media/

FileBrowser upload fails

Check:

  1. Disk space: df -h
  2. File size limits (default: unlimited)
  3. Browser console for errors
  4. Logs: docker-compose logs filebrowser

Increase upload size (if behind Nginx):

client_max_body_size 10G;

Transcoding fails / Buffering issues

Solutions:

  1. Enable hardware acceleration
  2. Lower streaming quality in Jellyfin settings
  3. Check network bandwidth
  4. Pre-transcode files:
ffmpeg -i input.mkv -c:v libx264 -preset slow -crf 22 output.mp4

Can't access remotely

Check:

  1. Firewall rules: sudo ufw status
  2. Port forwarding on router
  3. Server's local IP vs public IP
  4. Use Cloudflare Tunnel or VPN instead

Performance Optimization

Storage

  • Use SSD for Jellyfin config/cache (faster metadata)
  • Use HDD for media files (cheaper per GB)
  • Enable RAID for data redundancy

Network

  • Gigabit ethernet for server (no WiFi)
  • MoCA adapters if ethernet not possible
  • QoS rules to prioritize streaming traffic

Transcoding

  • Hardware acceleration (GPU) saves CPU
  • Pre-transcode large files to H264
  • Limit concurrent streams per user
  • Use Jellyfin's trickplay for thumbnails

Security Best Practices

  1. Strong passwords for all accounts
  2. HTTPS only for remote access (use reverse proxy)
  3. Disable admin on public internet (use VPN)
  4. Regular updates: docker-compose pull && docker-compose up -d
  5. Firewall rules: Only expose necessary ports
  6. Read-only media for Jellyfin (already configured above)
  7. Backup regularly (3-2-1 rule)

Cost Comparison

Self-Hosted (FileBrowser + Jellyfin)

Initial:

  • Used PC/Raspberry Pi: $50-$200
  • External HDD (4TB): $80-$100

Ongoing:

  • Electricity: ~$5-15/month
  • Internet: $0 (existing)
  • Domain (optional): $10-15/year

Total first year: ~$200-350
Annual after: ~$60-180

Commercial Alternatives

  • Netflix: $15.49/month = $186/year
  • Hulu: $14.99/month = $180/year
  • Disney+: $10.99/month = $132/year
  • Amazon Prime: $14.99/month = $180/year

Total for all four: $678/year

Break-even: ~6 months with self-hosted!

Plus you own your content forever and have unlimited storage.

Use Cases

Family Media Server

  • Parents upload family videos via FileBrowser
  • Kids watch cartoons on tablets (Jellyfin app)
  • Grandparents access via smart TV
  • Everyone has their own watchlist

Shared House / Dorm

  • Roommates contribute movies
  • Each person has own Jellyfin account
  • FileBrowser quotas prevent storage hogging
  • Watch parties via Jellyfin SyncPlay

Content Creator

  • Store raw footage in FileBrowser
  • Organize by project/date
  • Share preview links with clients
  • Archive completed projects

Language Learning

  • Upload movies/shows in target language
  • Jellyfin's subtitle support
  • Repeat viewing for practice
  • Build personal learning library

Conclusion

Combining FileBrowser and Jellyfin creates a powerful, self-hosted streaming platform that rivals commercial services while giving you complete control.

Key benefits:

Own your media - No licensing issues, no content removal
No monthly fees - One-time hardware cost
Unlimited storage - Add drives as needed
Privacy - Your viewing habits stay private
Customization - Full control over features and UI
Family sharing - No per-user fees
Remote access - Watch from anywhere
File management - Easy media organization via web interface

You should try this if:

  • You have a large media collection
  • You're tired of subscription fatigue
  • You want to share with family/friends
  • You value privacy and control
  • You enjoy self-hosting projects

Start small: Set up on an old laptop with a few movies. Once you see how well it works, invest in proper hardware and storage.

Happy streaming! 🎬

Resources


Built your own streaming service? Share your setup in the comments! Questions about configuration? Drop them below.

Written by

Found this helpful? Share your thoughts on GitHub