I have been building Lunarr, a self-hosted web media server for people who want to scan, organize, and watch their own movie and TV libraries in the browser.
It is still early, but the core idea is simple:
Add local or SFTP media libraries, scan them, match metadata, and play them through a clean web UI.
Lunarr is not trying to replace Plex or Jellyfin overnight. Those projects are mature and cover a huge surface area. Lunarr is currently focused on being small, direct, and practical for self-hosted setups where media may live on the same machine or on remote SFTP storage.
What Lunarr does today
Lunarr currently supports:
- Local movie and TV libraries
- SFTP movie and TV libraries
- TMDb metadata matching
- Movie, show, season, and episode organization
- Browser playback
- Direct streaming when the browser can play the file
- Temporary HLS remux/transcode when needed
- Seekable request-driven HLS playback
- Sidecar
.vttsubtitle detection - Admin/user accounts
- Library sharing controls
- Manual scans, scheduled scans, and local file watching
- Docker deployment
The SFTP support is one of the important parts for me. A lot of self-hosted setups do not keep media on the same machine as the web app. Lunarr can scan remote folders and, when possible, play seekable remote media without first copying the whole file locally.
Playback model
Lunarr tries direct playback first when the browser can handle the file.
When direct playback is not suitable, Lunarr uses temporary HLS playback. Instead of transcoding an entire movie up front, it generates segments around what the player is actually requesting.
For example, if you jump from 55 minutes to 13 minutes and then to 80 minutes, Lunarr does not transcode everything between those points. It repositions FFmpeg, generates the requested segment, and prepares a small lookahead window so playback can continue.
That keeps CPU and disk usage more proportional to what the viewer is actually watching.
Quick start with Docker
docker run -d \
--name lunarr \
--restart unless-stopped \
-p 3000:3000 \
-e AUTH_SECRET=replace-with-a-random-secret-at-least-32-chars \
-e ORIGIN=http://127.0.0.1:3000 \
-v lunarr-data:/data \
-v /mnt/media:/media:ro \
sayem314/lunarr:latest
Then open:
http://127.0.0.1:3000
Create the first admin account, add a movie or TV library, and start a scan.
For local media, mount your host media folder into the container and add the container path, for example /media.
For SFTP media, add the remote connection from the Libraries page.
Why build another media server?
Mostly because I wanted a focused project with a modern web stack, clear internals, and first-class support for both local and SFTP libraries.
Some goals:
- Keep deployment simple
- Make scanning behavior visible
- Keep playback temporary and cleanup-friendly
- Avoid requiring users to reorganize everything perfectly
- Support browser playback without pretending every file is browser-native
- Build something easier to iterate on while still being useful
Current status
Lunarr is beta software. It works, but there are still areas where mature media servers are ahead, especially around the long tail of media containers, subtitle formats, adaptive bitrate streaming, and unusual timestamp/keyframe edge cases.
The current focus is reliability: scanning, playback sessions, seeking behavior, cleanup, and Docker-based deployment.
Tech stack
Lunarr currently uses:
- SvelteKit
- Bun/Node
- SQLite/libSQL
- FFmpeg for remux/transcoding
- NodeAV for metadata/probing
- Docker for easier deployment
Try it
Docker image:
https://hub.docker.com/r/sayem314/lunarr
GitHub:
https://github.com/lunarr-app/lunarr-go
Feedback is welcome, especially from people running self-hosted media setups with local disks, SFTP storage, or mixed libraries.
Top comments (0)