MeTube is a self-hosted web UI for yt-dlpā . Paste a link from YouTube or hundreds of other sitesā , and it downloads to your server:
š Guides, recipes and a troubleshooting FAQ live in the wikiā ā many feature requests are already a recipe there, so check it before filing one.

docker run -d -p 8081:8081 -v /path/to/downloads:/downloads ghcr.io/alexta69/metube
Or with Docker Compose:
services:
metube:
image: ghcr.io/alexta69/metube
container_name: metube
restart: unless-stopped
ports:
- "8081:8081"
volumes:
- /path/to/downloads:/downloads
Then open http://<host>:8081 in your browser. Images are multi-arch (amd64/arm64), and also published on Docker Hub as alexta69/metube.
MeTube is configured with environment variables: -e NAME=value on the docker run command line, or the environment: section in Compose. Defaults are the Docker image's; outside Docker, the directories default to the working directory.
| Variable | Default | Description |
|---|---|---|
PUID / PGID | 1000 | User and group MeTube runs as and writes files with. Legacy UID/GID also work. |
UMASK | 022 | Umask for the files MeTube creates. |
CHOWN_DIRS | true | Make PUID:PGID the owner of the download, state and temp directories at startup. With false, MeTube's user must already have access. |
LOGLEVEL | INFO | DEBUG, INFO, WARNING, ERROR, CRITICAL or NONE. |
ENABLE_ACCESSLOG | false | Log every HTTP request. |
DEFAULT_THEME | auto | UI theme: light, dark, or auto to follow the system. |
| Variable | Default | Description |
|---|---|---|
MAX_CONCURRENT_DOWNLOADS | 3 | Downloads that run at once; the rest wait their turn. |
DEFAULT_OPTION_PLAYLIST_ITEM_LIMIT | 0 | Default for the Items Limit field: how many entries of a playlist or channel to download (0 = all). |
CLEAR_COMPLETED_AFTER | 0 | Seconds before finished and failed downloads leave the Completed list (0 = never). |
DELETE_FILE_ON_TRASHCAN | false | Also delete the file from disk when its entry is removed from Completed. |
SUBSCRIPTION_DEFAULT_CHECK_INTERVAL | 60 | Default minutes between checks of a subscriptionā . |
SUBSCRIPTION_SCAN_PLAYLIST_END | 50 | Newest entries fetched each time a subscription is checked. |
SUBSCRIPTION_MAX_SEEN_IDS | 50000 | Video IDs remembered per subscription, to bound the state file's size. |
| Variable | Default | Description |
|---|---|---|
DOWNLOAD_DIR | /downloads | Where downloads are saved. |
AUDIO_DOWNLOAD_DIR | same as DOWNLOAD_DIR | Where audio-only downloads are saved, to keep them apart from video. |
TEMP_DIR | /downloads | Where files are written while downloading. An SSD or tmpfs is faster, but on a RAM disk interrupted downloads can't resume. |
STATE_DIR | /downloads/.metube | Where MeTube keeps its queue, history, subscriptions and uploaded cookies. |
CUSTOM_DIRS | true | Show a Download Folder field under Advanced Options, to save into a subfolder of the download directory. |
CREATE_CUSTOM_DIRS | true | Let that field create folders that don't exist yet. |
CUSTOM_DIRS_EXCLUDE_REGEX | (^|/)[.@].*$ | Folders left out of the field's suggestions; the default hides names starting with . or @. Empty hides none. |
DEFAULT_FOLDER | Folder the field starts with, relative to the download directory. Requires CUSTOM_DIRS. | |
DOWNLOAD_DIRS_INDEXABLE | false | Serve browsable listings of the download directories. |
Templates use yt-dlp's output template syntaxā . How MeTube applies them is explained in Output templatesā .
| Variable | Default | Description |
|---|---|---|
OUTPUT_TEMPLATE | %(title)s.%(ext)s | Filename for downloads. |
OUTPUT_TEMPLATE_PLAYLIST | %(playlist_title)s/%(title)s.%(ext)s | Filename for items added from a playlist. Empty means OUTPUT_TEMPLATE. |
OUTPUT_TEMPLATE_CHANNEL | %(channel)s/%(title)s.%(ext)s | Filename for items added from a channel. Empty means OUTPUT_TEMPLATE. |
OUTPUT_TEMPLATE_CHAPTER | %(title)s - %(section_number)02d - %(section_title)s.%(ext)s | Default filename for each chapter when Split by chapters is on. |
| Variable | Default | Description |
|---|---|---|
YTDL_OPTIONS | {} | Options for every download, as a JSON object ā see yt-dlp optionsā . |
YTDL_OPTIONS_FILE | Path to a JSON file of such options. Reloaded when it changes; wins over YTDL_OPTIONS for the same key. | |
YTDL_OPTIONS_PRESETS | {} | Named option bundles, picked per download in the UI. |
YTDL_OPTIONS_PRESETS_FILE | Path to a JSON file of presets. Reloaded when it changes; wins over YTDL_OPTIONS_PRESETS for the same name. | |
ALLOW_YTDL_OPTIONS_OVERRIDES | false | Show a field for per-download yt-dlp options in the UI. Trusted users only: it allows running commands in the container. |
YTDL_NIGHTLY_UPDATE_TIME | Use nightly yt-dlp buildsā , upgrading and restarting daily at this time (HH:MM, 24-hour). |
| Variable | Default | Description |
|---|---|---|
HOST | 0.0.0.0 | Address to listen on. The default is every IPv4 interface; * (or empty) adds IPv6; :: is IPv6 only. |
PORT | 8081 | Port to listen on. |
URL_PREFIX | / | Base path, for serving MeTube under a subpath of a reverse proxyā . |
HTTPS | false | Serve HTTPS directly, using CERTFILE and KEYFILE. |
CERTFILE / KEYFILE | Paths to the HTTPS certificate and key. | |
PUBLIC_HOST_URL | download/ | Base URL for the links to completed files. The default is relative to MeTube itself; set a full URL if the files are served from elsewhere. |
PUBLIC_HOST_AUDIO_URL | audio_download/ | The same, for audio downloads. |
CORS_ALLOWED_ORIGINS | Comma-separated origins allowed to call MeTube from other sites, as browser extensions and bookmarkletsā do. * allows any site, so prefer naming them. | |
ALLOW_PRIVATE_ADDRESSES | false | Allow URLs on private and internal addresses, turning off SSRF protection. Needed for Fake-IP proxy clients, not for ordinary proxies ā detailsā . |
ROBOTS_TXT | Path to a robots.txt file to serve, mounted into the container. |
yt-dlp options are JSON objects keyed by yt-dlp's API option namesā , which differ from its command-line flags (converterā ). They apply at three levels, and for an option set at more than one, the more specific level wins:
YTDL_OPTIONS and YTDL_OPTIONS_FILE, for every download.YTDL_OPTIONS_PRESETS and YTDL_OPTIONS_PRESETS_FILE, picked per download under Advanced Options.ALLOW_YTDL_OPTIONS_OVERRIDES is on.environment:
- 'YTDL_OPTIONS={"writesubtitles": true, "subtitleslangs": ["en", "de"], "updatetime": false}'
The yt-dlp options guideā covers presets, overrides and option files in detail, and the YTDL_OPTIONS Cookbookā has ready-made recipes.
The wikiā covers everything beyond the reference above:
Sites change constantly, and yt-dlp keeps up with frequent releases. A new MeTube image is published automatically for every yt-dlp stable release, so keep your container updated ā watchtowerā can do it for you. To follow yt-dlp's nightly builds instead, set YTDL_NIGHTLY_UPDATE_TIME.
MeTube is only a UI for yt-dlp, so most download failures are yt-dlp's. Reproduce them with yt-dlp inside the container, and once a set of options works there, carry it over to YTDL_OPTIONS:
docker exec -ti metube sh
cd /downloads
yt-dlp <url>
The Troubleshooting FAQā covers common problems. Ask questions in Discussionsā ; issuesā are for bugs in MeTube itself.
MeTube's scope is deliberately narrow: it downloads well, and stops once the file is written. Tagging and library organization belong to dedicated tools ā point beetsā (headless, scriptable), MusicBrainz Picardā (GUI, acoustic fingerprinting) or Lidarrā (full library manager) at your AUDIO_DOWNLOAD_DIR.
Feature requests that fit this scope are welcome, and so are pull requests ā for a change that isn't obvious, start a discussion first. CONTRIBUTING.mdā has the scope policy and how to build and run MeTube locally.
Content type
Image
Digest
sha256:8a72943feā¦
Size
302.6 MB
Last updated
about 2 hours ago
docker pull alexta69/metube