HomeTube is a friendly video downloader managing single video URL into organized content structure for automatic home media server experience.
See the codeπ‘ Universal Video Downloader for Your Media Server
Download, process, and organize ads-free best-quality videos at Home.
β¨ HomeTube's workflow has grown into a platform: Content
A new self-hosted engine built on the same idea, taken further: URLs, files and text in β media, transcripts, summaries, translations and documents out. It ships a HomeTube app of its own, plus Content Studio, a REST API, a Python SDK and CLI, a browser extension, and an MCP server your AI agents can drive. HomeTube keeps being developed and maintained β Content is where the idea goes next.
Don't want to set up Docker yet? Try HomeTube in your browser β sign in with your email, and process your first videos on a free quota. Hit the quota and there are two ways on, both fine by us: self-host it for free, forever (that's what this repository is for), or let someone else run the server.
π¬ HomeTube is a simple web UI for downloading single videos and playlists from the internet with the highest quality available and moving them to specific local locations automatically managed and integrated by media server such as Plex or Jellyfin.
A simple friendly solution for easily integrating preferred videos from Youtube and others platforms to local media server:
Automatic integration with self-hosted setup:
Tech/Python/Advanced)Setup your HomeLab integration.
Automatically skip sponsors, ads, and promotional content with built-in SponsorBlock support. Just download your video and sponsors segments are automatically detected and marked.
Learn more about SponsorBlock features.
Cookies authentication should be setup for optimal video downloading experience and to avoid common download failures.
Even for public YouTube videos, cookies are increasingly necessary because of modern protections.
They ensure higher quality, reliability, and access to all formats:
π In short: cookies are not just for private content β theyβre the key to consistent, best-quality downloads.
We can use Browser cookies if on a machine sharing a browser, otherwise Cookies File in HomeLab setup.
More details about Cookies authentication setup.
Transform your downloads with powerful built-in video processing tools:
Explore all processing options.
Custom yt-dlp arguments support offers full flexibility for advanced users to tailor downloads to specific needs.
--proxy http://proxy.company.com:8080 --retries 5--max-filesize 500M --min-filesize 100M--write-info-json --write-description --write-thumbnail--limit-rate 1M --fragment-retries 10yt-dlp --options variableCustom yt-dlp arguments can be added directly from the UI or set by default for any download with the YTDLP_CUSTOM_ARGS environment variable.
π Smart Conflict Resolution: HomeTube automatically detects and resolves conflicts between base settings and custom arguments, giving priority to your custom preferences while maintaining system stability.
HomeTube uses intelligent quality detection that analyzes each video and automatically selects the best available formats with a simple 2-profile strategy:
π How It Works:
Quality Profiles Generated:
Download Strategies:
π Benefits:
π Full details on quality detection & strategies
Intelligent download system that adapts to your needs:
Learn more about download features.
Powerful playlist synchronization with resilient tracking and perfect source fidelity:
π Smart Synchronization:
π Resilient Video Tracking:
{idx}, {title}, {channel}, etc.)π‘οΈ Robust Change Detection:
π¨ Customizable Title Patterns:
{idx} - {pretty(title)}.{ext} β 01 - My Video Title.mkv
{pretty(title)} - {channel}.{ext} β My Video - Creator Name.mkv
{i:03d} - {slug(title)} [{id}].{ext} β 001 - my-video-title [abc123].mkv
Supported placeholders:
{idx} - Smart zero-padded index (01, 02... or 001, 002... based on total){title} / {pretty(title)} / {slug(title)} - Video title variants{channel} / {pretty(channel)} / {slug(channel)} - Channel name variants{id} - Video ID β’ {ext} - File extensionπ Progress Tracking:
Set PLAYLIST_KEEP_OLD_VIDEOS=true (or enable Keep videos removed from playlist in the UI) to move removed entries into an Archives/ folder instead of deleting them.
1800+ supported platforms - way beyond just YouTube:
π HomeTube uses environment variables for all configurations: videos download paths, temporary download folder, authentication, languages, quality profiles, and more.
Depending of the setup, Docker, Docker compose, Portainer, local run, environment variables can be passed to the application in different ways.
.env file from .env.sample can be practical for rapid setup:
# 1. Clone repository (if not already done)
git clone https://github.com/EgalitarianMonkey/hometube.git
cd hometube
# 2. Create your own configuration file from the sample
cp .env.sample .env
With Docker, environment variables can be passed either with -e VARIABLE= arguments or --env-file .env.
-e VARIABLE=
docker run -p 8501:8501 \
-e TZ=America/New_York \
-e VIDEOS_FOLDER=/data/videos \
-e TMP_DOWNLOAD_FOLDER=/data/tmp \
-e YOUTUBE_COOKIES_FILE_PATH=/config/youtube_cookies.txt \
-v <VIDEOS_FOLDER_DOCKER_HOST>:/data/videos \
-v <TMP_DOWNLOAD_FOLDER_DOCKER_HOST>:/data/tmp \
-v <YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST>:/config \
ghcr.io/egalitarianmonkey/hometube:latest
--env-file .env
docker run -p 8501:8501 \
--env-file .env \
-v <VIDEOS_FOLDER_DOCKER_HOST>:/data/videos \
-v <TMP_DOWNLOAD_FOLDER_DOCKER_HOST>:/data/tmp \
-v <YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST>:/config \
ghcr.io/egalitarianmonkey/hometube:latest
Access at http://localhost:8501
With Docker compose, environment variables can be passed either with the environment: entry or from the convenient .env file with env_file: .env.
.env file.env
# --- PORT ---
PORT=8510
# --- Timezone ---
TZ=America/New_York
# --- Languages ---
UI_LANGUAGE=en
LANGUAGE_PRIMARY=en
LANGUAGE_PRIMARY_INCLUDE_SUBTITLES=true
LANGUAGES_SECONDARIES= # Optional: comma-separated (e.g., fr,es)
# --- Docker host paths ---
# Docker environment variables to specify depending on your homelab setup.
VIDEOS_FOLDER_DOCKER_HOST=/mnt/data/videos
TMP_DOWNLOAD_FOLDER_DOCKER_HOST=/mnt/data/hometube/tmp
YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST=/opt/cookies/youtube.txt
# --- Paths ---
# Internal Docker container paths (do not change)
VIDEOS_FOLDER=/data/videos
TMP_DOWNLOAD_FOLDER=/data/tmp
YOUTUBE_COOKIES_FILE_PATH=/config/youtube_cookies.txt
#COOKIES_FROM_BROWSER=brave # Not working natively in Docker
docker-compose.yml
services:
hometube:
image: ghcr.io/egalitarianmonkey/hometube:latest
env_file: .env
volumes:
- type: bind
source: ${VIDEOS_FOLDER_DOCKER_HOST:?set VIDEOS_FOLDER_DOCKER_HOST}
target: /data/videos
- type: bind
source: ${TMP_DOWNLOAD_FOLDER_DOCKER_HOST:?set TMP_DOWNLOAD_FOLDER_DOCKER_HOST}
target: /data/tmp
- "${YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST}:/config/youtube_cookies.txt"
This long volume structure with type:, source:, and target: entries forces the environment variables to be set, otherwise the Docker deployment fails. This avoids silent failures and confusions when environment variables are missing.
environment::docker-compose.yml
services:
hometube:
image: ghcr.io/egalitarianmonkey/hometube:latest
environment:
UI_LANGUAGE: en
LANGUAGE_PRIMARY: en
LANGUAGE_PRIMARY_INCLUDE_SUBTITLES: true
LANGUAGES_SECONDARIES: "" # Optional: comma-separated
VIDEOS_FOLDER: /data/videos
TMP_DOWNLOAD_FOLDER: /data/tmp
YOUTUBE_COOKIES_FILE_PATH: /config/youtube_cookies.txt
volumes:
- type: bind
source: ${VIDEOS_FOLDER_DOCKER_HOST:?set VIDEOS_FOLDER_DOCKER_HOST}
target: /data/videos
- type: bind
source: ${TMP_DOWNLOAD_FOLDER_DOCKER_HOST:?set TMP_DOWNLOAD_FOLDER_DOCKER_HOST}
target: /data/tmp
- "${YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST}:/config/youtube_cookies.txt"
This long volume structure with type:, source:, and target: entries forces the environment variables to be set, otherwise the Docker deployment fails. This avoids silent failures and confusions when environment variables are missing.
Access at http://localhost:8501
With Portainer, environment variables must be explicitly written in the environment: section of the container setup to get those environment variables in the app.
env_file: entry for passing environment variables in the container from a .env file involving that the environment variables must be explicitly written in the environment: section of the container setup to get those environment variables in the app..env file as the stack isn't linked to any location. Environment variables for the Portainer docker-compose.yml stack must be manually entered from the UI either one by one or with a convenient .env upload.docker-compose.yml
services:
hometube:
image: ghcr.io/egalitarianmonkey/hometube:latest
ports:
- "${PORT:-8501}:8501"
environment:
TZ: "${TZ}"
UI_LANGUAGE: en
LANGUAGE_PRIMARY: en
LANGUAGE_PRIMARY_INCLUDE_SUBTITLES: true
LANGUAGES_SECONDARIES: "" # Optional: comma-separated
VIDEOS_FOLDER: /data/videos
TMP_DOWNLOAD_FOLDER: /data/tmp
YOUTUBE_COOKIES_FILE_PATH: "${YOUTUBE_COOKIES_FILE_PATH}"
volumes:
- type: bind
source: ${VIDEOS_FOLDER_DOCKER_HOST:?set VIDEOS_FOLDER_DOCKER_HOST}
target: /data/videos
- type: bind
source: ${TMP_DOWNLOAD_FOLDER_DOCKER_HOST:?set TMP_DOWNLOAD_FOLDER_DOCKER_HOST}
target: /data/tmp
- "${YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST}:/config/youtube_cookies.txt"
This long volume structure with type:, source:, and target: entries forces the environment variables to be set, otherwise the Docker deployment fails. This avoids silent failures and confusions when environment variables are missing.
Portainer environment variables in the UI
VIDEOS_FOLDER_DOCKER_HOST=/mnt/data/videos
TMP_DOWNLOAD_FOLDER_DOCKER_HOST=/mnt/data/hometube/tmp
YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST=/opt/cookies/youtube.txt
TZ=America/New_York
PORT=8501
YOUTUBE_COOKIES_FILE_PATH=/config/youtube_cookies.txt
#COOKIES_FROM_BROWSER=chrome
Environment variables for local run are setup following a specific order:
export VIDEOS_DIR=/data/videos, set -a && source .env && set +a, etc.).env file exists, not defined environment variables from exported shell will be taken from local .env file.env filePrerequisites are installed through python environment setup. Below are setups for venv, conda, or uv.
Option 1: Using pip (Recommended)
# Create virtual environment
python -m venv hometube-env
source hometube-env/bin/activate # On Windows: hometube-env\Scripts\activate
# Install dependencies including yt-dlp
pip install ".[local]"
# Run the application
streamlit run app/main.py
# OR
python run.py
Option 2: Using conda
# Create conda environment
conda create -n hometube python=3.10
conda activate hometube
# Install dependencies including yt-dlp
pip install ".[local]"
# Run the application
streamlit run app/main.py
Option 3: Using uv (Fastest)
# Install uv if not already installed
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies including yt-dlp
uv pip install ".[local]"
# Run with uv
uv run streamlit run app/main.py
Access at: http://localhost:8501
HomeTube configuration is managed through the .env file:
| Variable | Purpose | Defaults | Examples |
|---|---|---|---|
| Core Paths & System | |||
VIDEOS_FOLDER | Where videos will be moved at the end of download | /data/videos if in Docker container else ./downloads | /data/videos |
TMP_DOWNLOAD_FOLDER | Temporary download location | /data/tmp if in Docker container else ./tmp | /data/tmp |
PORT | Web interface port | 8501 | 8501 |
TZ | Timezone for Docker | America/New_York | Europe/Paris |
DEBUG | Debug logging mode | false | true |
| Authentication & Cookies | |||
YOUTUBE_COOKIES_FILE_PATH | Authentication for private videos | Must be defined (or COOKIES_FROM_BROWSER) | /config/youtube_cookies.txt |
COOKIES_FROM_BROWSER | Cookies auth directly from active local browser | chrome,firefox,brave,chromium,edge,opera,safari,vivaldi,whale | |
BROWSER_SELECT | Default browser for cookie extraction | chrome | chrome,firefox,edge,safari |
| Localization | |||
UI_LANGUAGE | UI language. English (en) and French (fr) supported | en | en,fr |
| Audio Language Preferences | |||
LANGUAGE_PRIMARY | Primary audio language preference | en | en,fr,es,de,ja |
LANGUAGES_SECONDARIES | Secondary audio languages (comma-separated) | (empty) | en,es,de |
LANGUAGE_PRIMARY_INCLUDE_SUBTITLES | Include subtitles for primary language | true | true,false |
VO_FIRST | Prioritize original voice (VO) before primary language | true | true,false |
| Quality & Download Preferences | |||
VIDEO_QUALITY_MAX | Maximum video resolution limit | max | max,2160,1440,1080,720,480,360 |
QUALITY_DOWNGRADE | Allow quality downgrade if best profile fails (false = best quality only, no fallback) | true | true,false |
EMBED_CHAPTERS | Embed chapters by default | true | true,false |
EMBED_SUBTITLES | Embed subtitles by default | true | true,false |
CUTTING_MODE | Video cutting precision | keyframes | keyframes,precise |
| Playlist Sync | |||
PLAYLIST_KEEP_OLD_VIDEOS | Archive playlist videos removed upstream instead of deleting them (moved to Archives/) | false | true,false |
| Safety Options | |||
ALLOW_OVERWRITE_EXISTING_VIDEO | Allow overwriting existing videos in destination folder | false | true,false (false = protect existing files) |
| Advanced Options | |||
YTDLP_CUSTOM_ARGS | Custom yt-dlp arguments | --max-filesize 5M --write-info-json | |
REMOVE_TMP_FILES_AFTER_DOWNLOAD | Remove temporary files after successful download | false | true,false (false = keep for debugging/reuse) |
NEW_DOWNLOAD_WITHOUT_TMP_FILES | Clean tmp folder before each new download | false | true,false (true = fresh start, useful after errors) |
| Media server | |||
JELLYFIN_BASE_URL | Address of the Jellyfin server to notify after a download | https://jellyfin.local:8096 | |
JELLYFIN_API_KEY | API key allowed to request a library refresh | 0123456789abcdef0123456789abcdef | |
| Docker-specific Variables | |||
VIDEOS_FOLDER_DOCKER_HOST | Host videos folder in Docker context | Must be defined | /mnt/data/videos if in Docker container else /downloads |
TMP_DOWNLOAD_FOLDER_DOCKER_HOST | Host tmp download videos folder in Docker context | Must be defined | /mnt/data/hometube/tmp if in Docker container else ./tmp |
YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST | Youtube cookies file path in Docker context | Must be defined | /opt/cookies/youtube.txt if in Docker container else ./cookies/youtube_cookies.txt |
Check your setup with this command:
DEBUG=1 python -c "import app.main" 2>/dev/null
Expected output:
π§ HomeTube Configuration Summary:
π Videos folder: downloads
π Temp folder: tmp
β
Videos folder is ready: downloads
πͺ Cookies file: ./cookies/youtube_cookies.txt
π€ Subtitle languages: en, fr
β
Configuration file: .env
π Complete Documentation Hub: docs/README.md
| Component | Technology | Purpose |
|---|---|---|
| Backend | Python 3.10+, yt-dlp, FFmpeg | Core processing |
| Frontend | Streamlit | Web interface |
| Container | π³ jauderho/yt-dlp (Alpine + yt-dlp + FFmpeg) | Optimized deployment |
| CI/CD | GitHub Actions | Automation |
| Testing | pytest, coverage | Quality assurance |
| Dependencies | UV, conda, pip | Package management |
| Requirement | Minimum | Recommended |
|---|---|---|
| Python | 3.10+ | 3.11+ |
| FFmpeg | Latest | Latest |
| Storage | 2GB free | 10GB+ |
| Memory | 512MB | 2GB |
| Network | Broadband | High-speed |
app/, concentrated on the utility modules (details)HomeTube does one job well: getting videos from the internet into a clean, self-hosted library. That workflow has grown into a platform.
Content is a new self-hosted engine built on the same idea, taken further β URLs, files and text in; media, transcripts, summaries, translations, images, Markdown and PDF out. One backend, several independent front doors:
| Client | What it is for |
|---|---|
| HomeTube for Content | The focused YouTube video and playlist app, rebuilt on the engine (:8501) |
| Content Studio | The general-purpose web app for any source (:8502) |
| Chromium extension | Send the tab you are already on (unpacked, from the release zip) |
| MCP server | uv tool install content-mcp β Claude, your IDE, or any MCP-compatible agent |
| CLI Β· Python SDK | uv tool install content-cli Β· pip install content-sdk |
| REST API | Any language that speaks HTTP (:8010/docs) |
Where things stand. HomeTube is the mature one and keeps being developed β this release is one of them. Content is the newer, broader engine, and it is where the most ambitious capabilities are being built: everything above is available today, and the two run happily side by side. Try it whenever you are curious.
Two honest caveats before you do:
8501. Change one of them if you want to run the two side by side.mkdir content && cd content
curl -fsSLO https://raw.githubusercontent.com/LatentNoise/content/main/deploy/docker-compose.yml
curl -fsSL -o .env https://raw.githubusercontent.com/LatentNoise/content/main/.env.example
docker compose up -d
HomeTube for Content on http://localhost:8501, Content Studio on http://localhost:8502. Point CONTENT_DELIVERY_DIR_HOST at your media library in .env and its sub-folders become the destination choices.
For developers and contributors, comprehensive guides are available:
π Development Guide - Environment setup
π Contributing Guidelines - Workflow and best practices
Quick Setup Options:
Includes: Testing commands, workflows, code standards, and pull request process.
If you find HomeTube useful, consider supporting the project to help with development costs.
Every contribution is appreciated! π
HomeTube is free software under the GNU Affero General Public License, version 3 or later β see LICENSE for the full text.
Copyright Β© 2025-2026 Yann Orieult, sole author and maintainer. NOTICE records copyright and licensing, AUTHORS records authorship, and CONTRIBUTING.md sets out the terms that apply to contributions.
β If you find this project useful, please consider starring it!
β Star on GitHub β’ π Documentation β’ π³ Docker Hub β’ β Buy Me a Coffee
1,115 followers Β· starred Sep 2025
673 followers Β· starred Feb 2026
156 followers Β· starred Jan 2026
189 followers Β· starred Sep 2025
HomeTube is a friendly video downloader managing single video URL into organized content structure for automatic home media server experience.
See the codeπ‘ Universal Video Downloader for Your Media Server
Download, process, and organize ads-free best-quality videos at Home.
β¨ HomeTube's workflow has grown into a platform: Content
A new self-hosted engine built on the same idea, taken further: URLs, files and text in β media, transcripts, summaries, translations and documents out. It ships a HomeTube app of its own, plus Content Studio, a REST API, a Python SDK and CLI, a browser extension, and an MCP server your AI agents can drive. HomeTube keeps being developed and maintained β Content is where the idea goes next.
Don't want to set up Docker yet? Try HomeTube in your browser β sign in with your email, and process your first videos on a free quota. Hit the quota and there are two ways on, both fine by us: self-host it for free, forever (that's what this repository is for), or let someone else run the server.
π¬ HomeTube is a simple web UI for downloading single videos and playlists from the internet with the highest quality available and moving them to specific local locations automatically managed and integrated by media server such as Plex or Jellyfin.
A simple friendly solution for easily integrating preferred videos from Youtube and others platforms to local media server:
Automatic integration with self-hosted setup:
Tech/Python/Advanced)Setup your HomeLab integration.
Automatically skip sponsors, ads, and promotional content with built-in SponsorBlock support. Just download your video and sponsors segments are automatically detected and marked.
Learn more about SponsorBlock features.
Cookies authentication should be setup for optimal video downloading experience and to avoid common download failures.
Even for public YouTube videos, cookies are increasingly necessary because of modern protections.
They ensure higher quality, reliability, and access to all formats:
π In short: cookies are not just for private content β theyβre the key to consistent, best-quality downloads.
We can use Browser cookies if on a machine sharing a browser, otherwise Cookies File in HomeLab setup.
More details about Cookies authentication setup.
Transform your downloads with powerful built-in video processing tools:
Explore all processing options.
Custom yt-dlp arguments support offers full flexibility for advanced users to tailor downloads to specific needs.
--proxy http://proxy.company.com:8080 --retries 5--max-filesize 500M --min-filesize 100M--write-info-json --write-description --write-thumbnail--limit-rate 1M --fragment-retries 10yt-dlp --options variableCustom yt-dlp arguments can be added directly from the UI or set by default for any download with the YTDLP_CUSTOM_ARGS environment variable.
π Smart Conflict Resolution: HomeTube automatically detects and resolves conflicts between base settings and custom arguments, giving priority to your custom preferences while maintaining system stability.
HomeTube uses intelligent quality detection that analyzes each video and automatically selects the best available formats with a simple 2-profile strategy:
π How It Works:
Quality Profiles Generated:
Download Strategies:
π Benefits:
π Full details on quality detection & strategies
Intelligent download system that adapts to your needs:
Learn more about download features.
Powerful playlist synchronization with resilient tracking and perfect source fidelity:
π Smart Synchronization:
π Resilient Video Tracking:
{idx}, {title}, {channel}, etc.)π‘οΈ Robust Change Detection:
π¨ Customizable Title Patterns:
{idx} - {pretty(title)}.{ext} β 01 - My Video Title.mkv
{pretty(title)} - {channel}.{ext} β My Video - Creator Name.mkv
{i:03d} - {slug(title)} [{id}].{ext} β 001 - my-video-title [abc123].mkv
Supported placeholders:
{idx} - Smart zero-padded index (01, 02... or 001, 002... based on total){title} / {pretty(title)} / {slug(title)} - Video title variants{channel} / {pretty(channel)} / {slug(channel)} - Channel name variants{id} - Video ID β’ {ext} - File extensionπ Progress Tracking:
Set PLAYLIST_KEEP_OLD_VIDEOS=true (or enable Keep videos removed from playlist in the UI) to move removed entries into an Archives/ folder instead of deleting them.
1800+ supported platforms - way beyond just YouTube:
π HomeTube uses environment variables for all configurations: videos download paths, temporary download folder, authentication, languages, quality profiles, and more.
Depending of the setup, Docker, Docker compose, Portainer, local run, environment variables can be passed to the application in different ways.
.env file from .env.sample can be practical for rapid setup:
# 1. Clone repository (if not already done)
git clone https://github.com/EgalitarianMonkey/hometube.git
cd hometube
# 2. Create your own configuration file from the sample
cp .env.sample .env
With Docker, environment variables can be passed either with -e VARIABLE= arguments or --env-file .env.
-e VARIABLE=
docker run -p 8501:8501 \
-e TZ=America/New_York \
-e VIDEOS_FOLDER=/data/videos \
-e TMP_DOWNLOAD_FOLDER=/data/tmp \
-e YOUTUBE_COOKIES_FILE_PATH=/config/youtube_cookies.txt \
-v <VIDEOS_FOLDER_DOCKER_HOST>:/data/videos \
-v <TMP_DOWNLOAD_FOLDER_DOCKER_HOST>:/data/tmp \
-v <YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST>:/config \
ghcr.io/egalitarianmonkey/hometube:latest
--env-file .env
docker run -p 8501:8501 \
--env-file .env \
-v <VIDEOS_FOLDER_DOCKER_HOST>:/data/videos \
-v <TMP_DOWNLOAD_FOLDER_DOCKER_HOST>:/data/tmp \
-v <YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST>:/config \
ghcr.io/egalitarianmonkey/hometube:latest
Access at http://localhost:8501
With Docker compose, environment variables can be passed either with the environment: entry or from the convenient .env file with env_file: .env.
.env file.env
# --- PORT ---
PORT=8510
# --- Timezone ---
TZ=America/New_York
# --- Languages ---
UI_LANGUAGE=en
LANGUAGE_PRIMARY=en
LANGUAGE_PRIMARY_INCLUDE_SUBTITLES=true
LANGUAGES_SECONDARIES= # Optional: comma-separated (e.g., fr,es)
# --- Docker host paths ---
# Docker environment variables to specify depending on your homelab setup.
VIDEOS_FOLDER_DOCKER_HOST=/mnt/data/videos
TMP_DOWNLOAD_FOLDER_DOCKER_HOST=/mnt/data/hometube/tmp
YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST=/opt/cookies/youtube.txt
# --- Paths ---
# Internal Docker container paths (do not change)
VIDEOS_FOLDER=/data/videos
TMP_DOWNLOAD_FOLDER=/data/tmp
YOUTUBE_COOKIES_FILE_PATH=/config/youtube_cookies.txt
#COOKIES_FROM_BROWSER=brave # Not working natively in Docker
docker-compose.yml
services:
hometube:
image: ghcr.io/egalitarianmonkey/hometube:latest
env_file: .env
volumes:
- type: bind
source: ${VIDEOS_FOLDER_DOCKER_HOST:?set VIDEOS_FOLDER_DOCKER_HOST}
target: /data/videos
- type: bind
source: ${TMP_DOWNLOAD_FOLDER_DOCKER_HOST:?set TMP_DOWNLOAD_FOLDER_DOCKER_HOST}
target: /data/tmp
- "${YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST}:/config/youtube_cookies.txt"
This long volume structure with type:, source:, and target: entries forces the environment variables to be set, otherwise the Docker deployment fails. This avoids silent failures and confusions when environment variables are missing.
environment::docker-compose.yml
services:
hometube:
image: ghcr.io/egalitarianmonkey/hometube:latest
environment:
UI_LANGUAGE: en
LANGUAGE_PRIMARY: en
LANGUAGE_PRIMARY_INCLUDE_SUBTITLES: true
LANGUAGES_SECONDARIES: "" # Optional: comma-separated
VIDEOS_FOLDER: /data/videos
TMP_DOWNLOAD_FOLDER: /data/tmp
YOUTUBE_COOKIES_FILE_PATH: /config/youtube_cookies.txt
volumes:
- type: bind
source: ${VIDEOS_FOLDER_DOCKER_HOST:?set VIDEOS_FOLDER_DOCKER_HOST}
target: /data/videos
- type: bind
source: ${TMP_DOWNLOAD_FOLDER_DOCKER_HOST:?set TMP_DOWNLOAD_FOLDER_DOCKER_HOST}
target: /data/tmp
- "${YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST}:/config/youtube_cookies.txt"
This long volume structure with type:, source:, and target: entries forces the environment variables to be set, otherwise the Docker deployment fails. This avoids silent failures and confusions when environment variables are missing.
Access at http://localhost:8501
With Portainer, environment variables must be explicitly written in the environment: section of the container setup to get those environment variables in the app.
env_file: entry for passing environment variables in the container from a .env file involving that the environment variables must be explicitly written in the environment: section of the container setup to get those environment variables in the app..env file as the stack isn't linked to any location. Environment variables for the Portainer docker-compose.yml stack must be manually entered from the UI either one by one or with a convenient .env upload.docker-compose.yml
services:
hometube:
image: ghcr.io/egalitarianmonkey/hometube:latest
ports:
- "${PORT:-8501}:8501"
environment:
TZ: "${TZ}"
UI_LANGUAGE: en
LANGUAGE_PRIMARY: en
LANGUAGE_PRIMARY_INCLUDE_SUBTITLES: true
LANGUAGES_SECONDARIES: "" # Optional: comma-separated
VIDEOS_FOLDER: /data/videos
TMP_DOWNLOAD_FOLDER: /data/tmp
YOUTUBE_COOKIES_FILE_PATH: "${YOUTUBE_COOKIES_FILE_PATH}"
volumes:
- type: bind
source: ${VIDEOS_FOLDER_DOCKER_HOST:?set VIDEOS_FOLDER_DOCKER_HOST}
target: /data/videos
- type: bind
source: ${TMP_DOWNLOAD_FOLDER_DOCKER_HOST:?set TMP_DOWNLOAD_FOLDER_DOCKER_HOST}
target: /data/tmp
- "${YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST}:/config/youtube_cookies.txt"
This long volume structure with type:, source:, and target: entries forces the environment variables to be set, otherwise the Docker deployment fails. This avoids silent failures and confusions when environment variables are missing.
Portainer environment variables in the UI
VIDEOS_FOLDER_DOCKER_HOST=/mnt/data/videos
TMP_DOWNLOAD_FOLDER_DOCKER_HOST=/mnt/data/hometube/tmp
YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST=/opt/cookies/youtube.txt
TZ=America/New_York
PORT=8501
YOUTUBE_COOKIES_FILE_PATH=/config/youtube_cookies.txt
#COOKIES_FROM_BROWSER=chrome
Environment variables for local run are setup following a specific order:
export VIDEOS_DIR=/data/videos, set -a && source .env && set +a, etc.).env file exists, not defined environment variables from exported shell will be taken from local .env file.env filePrerequisites are installed through python environment setup. Below are setups for venv, conda, or uv.
Option 1: Using pip (Recommended)
# Create virtual environment
python -m venv hometube-env
source hometube-env/bin/activate # On Windows: hometube-env\Scripts\activate
# Install dependencies including yt-dlp
pip install ".[local]"
# Run the application
streamlit run app/main.py
# OR
python run.py
Option 2: Using conda
# Create conda environment
conda create -n hometube python=3.10
conda activate hometube
# Install dependencies including yt-dlp
pip install ".[local]"
# Run the application
streamlit run app/main.py
Option 3: Using uv (Fastest)
# Install uv if not already installed
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies including yt-dlp
uv pip install ".[local]"
# Run with uv
uv run streamlit run app/main.py
Access at: http://localhost:8501
HomeTube configuration is managed through the .env file:
| Variable | Purpose | Defaults | Examples |
|---|---|---|---|
| Core Paths & System | |||
VIDEOS_FOLDER | Where videos will be moved at the end of download | /data/videos if in Docker container else ./downloads | /data/videos |
TMP_DOWNLOAD_FOLDER | Temporary download location | /data/tmp if in Docker container else ./tmp | /data/tmp |
PORT | Web interface port | 8501 | 8501 |
TZ | Timezone for Docker | America/New_York | Europe/Paris |
DEBUG | Debug logging mode | false | true |
| Authentication & Cookies | |||
YOUTUBE_COOKIES_FILE_PATH | Authentication for private videos | Must be defined (or COOKIES_FROM_BROWSER) | /config/youtube_cookies.txt |
COOKIES_FROM_BROWSER | Cookies auth directly from active local browser | chrome,firefox,brave,chromium,edge,opera,safari,vivaldi,whale | |
BROWSER_SELECT | Default browser for cookie extraction | chrome | chrome,firefox,edge,safari |
| Localization | |||
UI_LANGUAGE | UI language. English (en) and French (fr) supported | en | en,fr |
| Audio Language Preferences | |||
LANGUAGE_PRIMARY | Primary audio language preference | en | en,fr,es,de,ja |
LANGUAGES_SECONDARIES | Secondary audio languages (comma-separated) | (empty) | en,es,de |
LANGUAGE_PRIMARY_INCLUDE_SUBTITLES | Include subtitles for primary language | true | true,false |
VO_FIRST | Prioritize original voice (VO) before primary language | true | true,false |
| Quality & Download Preferences | |||
VIDEO_QUALITY_MAX | Maximum video resolution limit | max | max,2160,1440,1080,720,480,360 |
QUALITY_DOWNGRADE | Allow quality downgrade if best profile fails (false = best quality only, no fallback) | true | true,false |
EMBED_CHAPTERS | Embed chapters by default | true | true,false |
EMBED_SUBTITLES | Embed subtitles by default | true | true,false |
CUTTING_MODE | Video cutting precision | keyframes | keyframes,precise |
| Playlist Sync | |||
PLAYLIST_KEEP_OLD_VIDEOS | Archive playlist videos removed upstream instead of deleting them (moved to Archives/) | false | true,false |
| Safety Options | |||
ALLOW_OVERWRITE_EXISTING_VIDEO | Allow overwriting existing videos in destination folder | false | true,false (false = protect existing files) |
| Advanced Options | |||
YTDLP_CUSTOM_ARGS | Custom yt-dlp arguments | --max-filesize 5M --write-info-json | |
REMOVE_TMP_FILES_AFTER_DOWNLOAD | Remove temporary files after successful download | false | true,false (false = keep for debugging/reuse) |
NEW_DOWNLOAD_WITHOUT_TMP_FILES | Clean tmp folder before each new download | false | true,false (true = fresh start, useful after errors) |
| Media server | |||
JELLYFIN_BASE_URL | Address of the Jellyfin server to notify after a download | https://jellyfin.local:8096 | |
JELLYFIN_API_KEY | API key allowed to request a library refresh | 0123456789abcdef0123456789abcdef | |
| Docker-specific Variables | |||
VIDEOS_FOLDER_DOCKER_HOST | Host videos folder in Docker context | Must be defined | /mnt/data/videos if in Docker container else /downloads |
TMP_DOWNLOAD_FOLDER_DOCKER_HOST | Host tmp download videos folder in Docker context | Must be defined | /mnt/data/hometube/tmp if in Docker container else ./tmp |
YOUTUBE_COOKIES_FILE_PATH_DOCKER_HOST | Youtube cookies file path in Docker context | Must be defined | /opt/cookies/youtube.txt if in Docker container else ./cookies/youtube_cookies.txt |
Check your setup with this command:
DEBUG=1 python -c "import app.main" 2>/dev/null
Expected output:
π§ HomeTube Configuration Summary:
π Videos folder: downloads
π Temp folder: tmp
β
Videos folder is ready: downloads
πͺ Cookies file: ./cookies/youtube_cookies.txt
π€ Subtitle languages: en, fr
β
Configuration file: .env
π Complete Documentation Hub: docs/README.md
| Component | Technology | Purpose |
|---|---|---|
| Backend | Python 3.10+, yt-dlp, FFmpeg | Core processing |
| Frontend | Streamlit | Web interface |
| Container | π³ jauderho/yt-dlp (Alpine + yt-dlp + FFmpeg) | Optimized deployment |
| CI/CD | GitHub Actions | Automation |
| Testing | pytest, coverage | Quality assurance |
| Dependencies | UV, conda, pip | Package management |
| Requirement | Minimum | Recommended |
|---|---|---|
| Python | 3.10+ | 3.11+ |
| FFmpeg | Latest | Latest |
| Storage | 2GB free | 10GB+ |
| Memory | 512MB | 2GB |
| Network | Broadband | High-speed |
app/, concentrated on the utility modules (details)HomeTube does one job well: getting videos from the internet into a clean, self-hosted library. That workflow has grown into a platform.
Content is a new self-hosted engine built on the same idea, taken further β URLs, files and text in; media, transcripts, summaries, translations, images, Markdown and PDF out. One backend, several independent front doors:
| Client | What it is for |
|---|---|
| HomeTube for Content | The focused YouTube video and playlist app, rebuilt on the engine (:8501) |
| Content Studio | The general-purpose web app for any source (:8502) |
| Chromium extension | Send the tab you are already on (unpacked, from the release zip) |
| MCP server | uv tool install content-mcp β Claude, your IDE, or any MCP-compatible agent |
| CLI Β· Python SDK | uv tool install content-cli Β· pip install content-sdk |
| REST API | Any language that speaks HTTP (:8010/docs) |
Where things stand. HomeTube is the mature one and keeps being developed β this release is one of them. Content is the newer, broader engine, and it is where the most ambitious capabilities are being built: everything above is available today, and the two run happily side by side. Try it whenever you are curious.
Two honest caveats before you do:
8501. Change one of them if you want to run the two side by side.mkdir content && cd content
curl -fsSLO https://raw.githubusercontent.com/LatentNoise/content/main/deploy/docker-compose.yml
curl -fsSL -o .env https://raw.githubusercontent.com/LatentNoise/content/main/.env.example
docker compose up -d
HomeTube for Content on http://localhost:8501, Content Studio on http://localhost:8502. Point CONTENT_DELIVERY_DIR_HOST at your media library in .env and its sub-folders become the destination choices.
For developers and contributors, comprehensive guides are available:
π Development Guide - Environment setup
π Contributing Guidelines - Workflow and best practices
Quick Setup Options:
Includes: Testing commands, workflows, code standards, and pull request process.
If you find HomeTube useful, consider supporting the project to help with development costs.
Every contribution is appreciated! π
HomeTube is free software under the GNU Affero General Public License, version 3 or later β see LICENSE for the full text.
Copyright Β© 2025-2026 Yann Orieult, sole author and maintainer. NOTICE records copyright and licensing, AUTHORS records authorship, and CONTRIBUTING.md sets out the terms that apply to contributions.
β If you find this project useful, please consider starring it!
β Star on GitHub β’ π Documentation β’ π³ Docker Hub β’ β Buy Me a Coffee
1,115 followers Β· starred Sep 2025
673 followers Β· starred Feb 2026
156 followers Β· starred Jan 2026
189 followers Β· starred Sep 2025