- Add mobile bottom tab bar for media browsing (Home, Libraries, Favourites, Playlists, More) - Split mobile drawer: media links first, admin links under a Management section - Show contextual back button in mobile header for deep routes - Add reusable PageBackButton and PageHeader components - Add back navigation to playlist detail, library page, and missing media state - Embed queue panels in TaskQueuePage to avoid duplicate page titles - Expose theme toggle in user menu on small screens Co-authored-by: truewhile <truewhile@users.noreply.github.com>
MMTL (My Movie and TV Library)
A self-hosted media center for NAS and home theater
Libraries · Metadata · Cloud STRM · Emby protocol · Remote Emby mounts · Multi-user · Docker-first
中文 · Overview · Quick Start · Deployment · Acknowledgements · Development
Overview
MMTL is a self-hosted private media management system for NAS, mini PCs, family sharing, and multi-device playback. This repository is a maintained fork of MediaStationGo, extended with stronger cloud playback, task queues, remote mounts, and permission controls.
In practice, MMTL gives you:
- A modern web media library
- An Emby/Jellyfin-compatible protocol gateway for third-party players
- A single panel for local disks, download folders, and cloud storage
Key capabilities
| Area | Highlights |
|---|---|
| Libraries | Movies, TV, anime, variety, music, custom libraries; multi-root scanning; poster wall; continue watching |
| Metadata | TMDb, Bangumi, Douban, TheTVDB, Fanart, NFO import, manual matching, scrape queue |
| Playback | Web player, HLS transcoding, danmaku, subtitles, play profiles, history and favourites |
| Emby protocol | Add MMTL in Infuse, SenPlayer, Fileball, etc. and sign in with MMTL accounts |
| Remote Emby mounts | Browse remote Emby libraries inside MMTL without a separate Emby client |
| Cloud & STRM | OpenList, CloudDrive2, 115, WebDAV; STRM sync; upload/download queues; direct or 302 playback |
| Downloads & organize | qBittorrent, site search/subscriptions, post-download organization, file manager |
| Users & permissions | Admin/regular users, expiry, NSFW toggle, play-profile PIN, granular permissions |
| Operations | Unified task queue, recycle bin, storage stats, DLNA casting, settings and logs |
Tech stack
- Backend: Go, Gin, GORM, SQLite or PostgreSQL, optional Redis and OpenSearch
- Frontend: React 18, Vite, TypeScript, Tailwind CSS, Zustand
- Deployment: Standalone Docker Compose templates, amd64/arm64 images, single-binary releases
Quick Start
Docker Compose is the recommended path. The repo ships four standalone templates; no .env is required.
mkdir -p MMTL && cd MMTL
# Simplest: one container with built-in SQLite
curl -fsSL https://raw.githubusercontent.com/truewhile/MMTL/main/docker-compose.simple.yml -o docker-compose.yml
# Or PostgreSQL tier for multi-user setups
# curl -fsSL https://raw.githubusercontent.com/truewhile/MMTL/main/docker-compose.yml -o docker-compose.yml
docker compose up -d
Open:
http://SERVER_IP:18080
Default login: admin / admin123 — change the password immediately.
Image:
ghcr.io/truewhile/mmtl:latest
Deployment tiers
Pick one compose file. Do not stack multiple -f files.
| Tier | File | Stack | Best for |
|---|---|---|---|
| Single image | docker-compose.simple.yml |
MMTL + SQLite | Beginners, single-user, low-resource NAS |
| Tier 1 | docker-compose.yml |
MMTL + PostgreSQL | Most home NAS deployments |
| Tier 2 | docker-compose.standard.yml |
+ Redis | Multi-user, frequent Emby client refreshes |
| Tier 3 | docker-compose.search.yml |
+ OpenSearch | Very large libraries, advanced full-text search |
Single-image notes
- Only one MMTL container; database lives in
./data/mmtl.db - Do not set
MMTL_DATABASE_DSNor it switches to PostgreSQL - Back up
./data;./cachecan be rebuilt
PostgreSQL notes
- Primary DB:
./postgres; secrets and runtime files:./data - Existing
./data/mmtl.dbmigrates automatically on first start - After migration, point
MMTL_DATABASE_DB_PATHat a non-existent file to disable re-checks
Backup
| Path | Notes |
|---|---|
./data |
JWT secret, config, SQLite DB or migration source |
./postgres |
PostgreSQL primary DB |
./cache, ./redis, ./opensearch |
Rebuildable |
Update
docker compose pull mmtl
docker compose up -d --no-deps mmtl
Path mapping
The most common Docker mistake is mixing host paths with container paths.
- Left side of
volumes= real host/NAS path - Right side = container path; use
/media/...in the web UI - Keep
MMTL_MEDIA_DIR/MMTL_DOWNLOAD_DIRaligned with mounts when organizing or ingesting downloads
Example:
volumes:
- /vol1/1000/Media:/media
- /vol1/1000/Downloads:/downloads
environment:
MMTL_MEDIA_DIR: /vol1/1000/Media
MMTL_MEDIA_CONTAINER_DIR: /media
MMTL_DOWNLOAD_DIR: /vol1/1000/Downloads
MMTL_DOWNLOAD_CONTAINER_DIR: /downloads
First-time setup
- Create a library with a container path such as
/media/Movies, then scan - Add metadata providers (TMDb, Bangumi, etc.) in system settings
- Optionally connect qBittorrent (
http://host.docker.internal:8085when qB runs on the host) - Optionally configure cloud accounts under STRM management
- Add the server in Emby-compatible players at
http://SERVER_IP:18080using MMTL credentials
FAQ
Library scan is slow
Check path mapping and DB tier. Cloud scans also depend on API limits and folder size.
qBittorrent downloads are not organized
Ensure the download directory is mounted into the container and env vars match.
Hardlink fails with cross-device link
Hardlinks require the same filesystem/subvolume; use copy or symlink across disks or cloud mounts.
External player cannot connect
Use http://IP:18080 and a MMTL user account; reverse proxies need correct external URL and HTTPS headers.
Development
The backend embeds web/dist via go:embed. Build the frontend first.
npm --prefix web ci
npm --prefix web run build
go test ./...
go run ./cmd/server
npm --prefix web run dev
Release builds ship single-file binaries for Windows, Linux, and macOS on amd64 and arm64.
Acknowledgements
MMTL is forked from and continues to evolve MediaStationGo. Thank you to the upstream project for the media-library architecture, Emby-protocol compatibility, and self-hosted foundation.
Many cloud sync, STRM, and media-organization ideas in this project were also informed by qmediasync. Thank you for the reference implementation and design patterns.
Contributing
See CONTRIBUTING.md and SECURITY.md before opening issues or pull requests.
Star History
License
This project is licensed under GPL-3.0.
