Self-Hosted Streaming with Jellyfin and ngrok – A Personal Weekend Project


It all started with a simple need — I wanted to watch some old movies and personal family videos stored on my desktop. My niece had also backed up a bunch of vacation clips from her phone onto my machine, and now that she’s back home, I needed an easy way to send them back to her without juggling USB drives or cloud uploads.
Being someone from a DevOps/SRE background, these small personal needs often spiral into fun infrastructure experiments. So, I figured, why not use this as a chance to self-host a media server?
That’s when I turned to Jellyfin — a free, open-source media streaming solution. Paired with ngrok
securely sharing access with family, I now had my very own private “Netflix” running directly from my Linux desktop. This was one of those side projects that started as a practical fix but turned into an unexpectedly enjoyable weekend build.
In this post, I’ll walk you through exactly how I set it all up using Docker and ngrok — clean, simple, and DevOps-style.
📌 Why Jellyfin?
As someone who values open-source tools and self-hosted alternatives, Jellyfin hits the sweet spot:
Fully open-source
No telemetry or licensing headaches
Supports local media, subtitles, transcoding, and even user profiles
I had a folder full of personal and family videos collecting digital dust. Jellyfin gave them a Netflix-like interface without the surveillance.
🐳 Step 1: Run Jellyfin in Docker
To keep things clean and reproducible (DevOps mantra!), I went with Docker.
docker run -d \
--name jellyfin \
-p 8096:8096 \
-v /home/user/Documents/p2p:/media \
jellyfin/jellyfin
A few things to note:
-d
runs it in the backgroundPort 8096 is Jellyfin’s default web UI
The
-v
mount points my local media directory into the container at/media
Once the container spins up, hit http://localhost:8096
on your browser and follow the setup wizard. You’ll be able to:
Create an admin account
Add your media libraries
Configure transcoding and user access
Simple and smooth.
🌍 Step 2: Access Jellyfin from Anywhere Using ngrok
Since I didn’t want to mess with router port forwarding or dynamic DNS at home (and certainly not expose ports to the internet unsafely), ngrok
was the perfect plug-and-play solution.
Install ngrok
wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz
tar -xvf ngrok-v3-stable-linux-amd64.tgz
sudo mv ngrok /usr/local/bin
ngrok version
You’ll need an ngrok account to get an auth token. Then:
ngrok config add-authtoken <YOUR_AUTH_TOKEN>
Create a Tunnel for Port 8096
ngrok http 8096
Boom! You’ll get a public HTTPS URL https://abc123.ngrok.io
that tunnels securely to your local Jellyfin instance.
Bonus: Protect it with Basic Auth
To prevent unauthorized access, use basic auth:
ngrok http -auth="username:password" 8096
Replace with your credentials. Now even if someone stumbles upon the link, they’ll need to authenticate first.
📦 Alternate: Run ngrok in Docker
If you like consistency (like me), you might prefer running ngrok
in a container too:
docker run -it \
-e NGROK_AUTHTOKEN=<YOUR_AUTH_TOKEN> \
ngrok/ngrok http 8096
Optional: include -auth="username:password"
in the command above if you want the same security via Docker.
🔒 A Quick Word on Security
This setup is intended for personal use. If you're planning to stream across multiple users or set up a family server, consider:
Running Jellyfin behind a proper reverse proxy (like Nginx)
Using a free domain with Let's Encrypt certs
Disabling public tunnels when not in use
Not exposing write access to the mounted media directory (read-only is safer)
🎯 Real-World Use Cases
Personal Netflix Clone – Watch your ripped DVDs or archived home videos from anywhere.
Test Media Playback Over Slow Networks – Useful if you’re tuning transcoding profiles for a home server.
Portable Demos – Great for showing media apps at meetups or events without deploying to a cloud server.
Media Backup Viewer – Remote preview of a NAS or cold storage drive contents.
🧠 Final Thoughts
For anyone in DevOps, self-hosting isn't just about saving money. It's about owning your stack, learning through tinkering, and reusing familiar tools (like Docker, tunneling, logs) in a low-stress, real-life scenario.
This Jellyfin + ngrok combo was less than an hour-long weekend project, but the satisfaction it gives — seeing your own media beautifully indexed and remotely accessible — is real.
Give it a try. This might just become your favorite side gig for relaxing after a long sprint.
If you found this helpful or tried something similar, I’d love to hear about your setup, tweaks, or war stories. Leave a comment on Hashnode or connect via LinkedIn, I’m always happy to connect and geek out about self-hosting and home lab fun.
Happy streaming! 🎥🍿
ImageCredits: Photo by Marques Kaspbrak on Unsplash
Subscribe to my newsletter
Read articles from Cyril Sebastian directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Cyril Sebastian
Cyril Sebastian
I’m Cyril Sebastian, a DevOps and Cloud Infrastructure architect with 10+ years of experience building, scaling, and securing cloud-native and hybrid systems. I specialize in automation, cost optimization, observability, and platform engineering across AWS, GCP, and Oracle Cloud. My passion lies in solving complex infrastructure challenges—from cloud migrations to Infrastructure as Code (IaC), and from deployment automation to scalable monitoring strategies. I blog here about: Cloud strategy and migration playbooks Real-world DevOps and automation with Terraform, Jenkins, and Ansible DevSecOps practices and security-first thinking in production Monitoring, cost optimization, and incident response at scale If you're building in the cloud, optimizing infra, or exploring DevOps culture—let’s connect and share ideas! 🔗 linkedin.com/in/sebastiancyril