Securing Jellyfin on the internet Securing Jellyfin on the internet

Securing Jellyfin when it's exposed to the internet

TL;DR Someone asked me on Reddit for a comprehensive guide to securing a public-facing Jellyfin instance, so here it is. The short answer I gave was: fail2ban, automate patching, implement OAuth, and download an IP block list. This post expands all four into actionable steps and adds a fifth option — IP whitelisting with a DDNS-aware Python cron job — plus the honest answer that a VPN eliminates most of this complexity entirely. ...

March 28, 2026 · 10 min · zolty
Self-hosted GitHub Actions cache server Self-hosted GitHub Actions cache server

Self-Hosting a GitHub Actions Cache Server on NAS Storage

TL;DR If you run self-hosted GitHub Actions runners, every actions/cache step is round-tripping to GitHub’s cloud storage. For a homelab cluster with local runners, that means cache restores travel from GitHub’s CDN to your runner, through your ISP, and back – even though the runner is 10 feet from your NAS. I deployed falcondev-oss/github-actions-cache-server as a Kubernetes deployment, pointed it at NFS storage on my NAS, set one environment variable on my runners, and flushed all the GitHub-hosted caches. Zero workflow changes required. ...

March 27, 2026 · 5 min · zolty
Jellyfin HA on Kubernetes Jellyfin HA on Kubernetes

Jellyfin HA on Kubernetes: Redis-Backed Transcode Session Failover

TL;DR Jellyfin dies mid-stream when a Kubernetes pod restarts because all transcode state is in-memory. I forked it, added a Redis-backed ITranscodeSessionStore, and wired in atomic lease-based pod takeover. The fork is at github.com/ZoltyMat/jellyfin-ha, and I also published a repo-level diff document at docs/FORK-DIFF.md showing exactly what changed versus upstream Jellyfin. Single-instance deployments need zero config changes because it falls back to a no-op store transparently. The Problem Jellyfin is great. It’s also built with the assumption that exactly one server instance is running at a time. Transcode state — which pods are running FFmpeg, what segments have been written, who owns a given play session — lives entirely in memory. When the process dies, that state is gone. ...

March 14, 2026 · 7 min · zolty

Affiliate Disclosure: Some links on this site are affiliate links (Amazon Associates, DigitalOcean referral). As an Amazon Associate, I earn from qualifying purchases. This does not affect the price you pay or my editorial independence — I only recommend products and services I personally use and trust.