Meet Lunarr: a self-hosted media server for local and SFTP libraries
Source: Dev.to
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.
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 .vtt subtitle 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.
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.
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. 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 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. Lunarr currently uses: SvelteKit Bun/Node SQLite/libSQL FFmpeg for remux/transcoding NodeAV for metadata/probing Docker for easier deployment 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.