alexta69/metube
DevOps & Self-hostingA self-hosted web interface for yt-dlp that downloads video, audio, subtitles and thumbnails to your own server.
What MeTube does
MeTube is a self-hosted web front end for yt-dlp. You paste a link from YouTube or one of the hundreds of other supported sites, and the server downloads video, audio, subtitles and thumbnails into a directory you control. It handles single videos, playlists and whole channels, and it can subscribe to channels or playlists so newly published items are queued automatically Subscriptions guide.
It targets people who want a browser-based downloader running on their own hardware, rather than a command line they have to remember. Each download can choose quality, format and destination folder, and server-wide yt-dlp options and named presets can be configured by an administrator.
Quick start
Docker is the supported path. Prepare a host directory for downloaded files, then run the image, mapping the web port and the download volume:
docker run -d -p 8081:8081 -v /path/to/downloads:/downloads ghcr.io/alexta69/metube
The equivalent Compose service looks like this:
services:
metube:
image: ghcr.io/alexta69/metube
container_name: metube
restart: unless-stopped
ports:
- "8081:8081"
volumes:
- /path/to/downloads:/downloads
Open http://<host>:8081 in a browser and paste a URL. Images are multi-arch for amd64 and arm64 and are also published on Docker Hub as alexta69/metube. The ghcr.io/alexta69/metube image is the current reference; replace /path/to/downloads with a real host path before starting.
Configuration is done through environment variables, either with -e NAME=value on docker run or under environment: in Compose. For example, to fetch English and German subtitles for every download:
environment:
- 'YTDL_OPTIONS={"writesubtitles": true, "subtitleslangs": ["en", "de"], "updatetime": false}'
Configuration and permissions
The container writes files as PUID/PGID, both defaulting to 1000. The legacy UID/GID names also work. CHOWN_DIRS defaults to true, which makes that user the owner of the download, state and temp directories at startup; with it set to false, the user must already have access. UMASK defaults to 022.
Directory defaults assume /downloads: it is the download directory, the temp directory while files are being written, and the parent of the state directory /downloads/.metube, which holds the queue, history, subscriptions and uploaded cookies. AUDIO_DOWNLOAD_DIR can separate audio-only downloads from video, and DOWNLOAD_DIR can point elsewhere. Putting the temp directory on a RAM disk is faster but prevents resuming interrupted downloads.
Concurrency is capped by MAX_CONCURRENT_DOWNLOADS (default 3); additional downloads wait. Output filenames use yt-dlp output templates, with separate defaults for plain videos, playlist items, channel items and chapter splitting Output templates.
yt-dlp options and scope
yt-dlp settings are JSON objects keyed by yt-dlp's API option names, not its command-line flags; the project points to a converter for the difference yt-dlp option names. Three levels apply, and the more specific level wins: global YTDL_OPTIONS or YTDL_OPTIONS_FILE, named presets under Advanced Options, and per-download overrides in the UI. Those overrides are disabled by default through ALLOW_YTDL_OPTIONS_OVERRIDES, because enabling them lets a user run commands in the container; the documentation limits this to trusted users yt-dlp options guide.
The project deliberately stops at downloading. Tagging and library management are left to tools such as beets, MusicBrainz Picard or Lidarr, which can be pointed at the audio directory scope notes.
Network and security choices
The web server listens on 0.0.0.0:8081 by default. HOST, PORT and URL_PREFIX support different bind addresses and reverse-proxy subpaths; HTTPS can be served directly with CERTFILE and KEYFILE reverse proxy examples. CORS_ALLOWED_ORIGINS is empty by default and is needed when browser extensions or bookmarklets call MeTube from another origin sending links.
SSRF protection is on by default. ALLOW_PRIVATE_ADDRESSES turns it off and is only required for Fake-IP style proxy clients, not ordinary proxies FAQ entry. The code is licensed AGPL-3.0.
Keeping yt-dlp current
Extraction breaks as sites change, and yt-dlp releases frequently. A new MeTube image is published for every stable yt-dlp release, so the container should be updated; Watchtower is suggested for automation. Setting YTDL_NIGHTLY_UPDATE_TIME in HH:MM form switches to nightly yt-dlp builds, upgrading and restarting daily at that time README section.
Troubleshooting
Most failed downloads are yt-dlp failures rather than MeTube bugs. The recommended diagnosis is to enter the container and run yt-dlp directly against the URL, then carry working options into YTDL_OPTIONS:
docker exec -ti metube sh
cd /downloads
yt-dlp <url>
Common problems are collected in the Troubleshooting FAQ; questions go to Discussions and reproducible bugs to issues.
HotRepo's take
There is no GitHub daily-rank history or star-sampling record for this repository in HotRepo, so the only activity signal is the discussion record. A July 2024 Hacker News thread drew 327 points and 164 comments thread, where the conversation mostly drifted to adjacent tools rather than testing MeTube: one commenter recommended Tube Archivist for indexing and full-text search comment, a reply preferred Pinchflat's single-container deployment reply, and another raised concerns that archival tools tied to a database should not depend on that database outliving the data comment. Others asked why a downloader needs a server at all, and replies noted that a local machine or container can be the server and that desktop alternatives exist comment. Read against the README, those threads frame MeTube's niche as a narrow web wrapper around yt-dlp with subscriptions, not a media library. Data quality note: the thread dates are from 2024 and may describe older versions.
Written by AI from the project's README, updated . The project's own docs are the source of truth.