Self-hosted web app for downloading videos or audio with yt-dlp, Docker, and optional proxy support.
1.0K
After pushing a new image to Docker Hub, you can refresh the deployment on your server like this:
mkdir -p ~/downloads ~/yt-dlp-plugins
sudo chown -R 999:999 ~/downloads ~/yt-dlp-plugins
docker pull marekotulakowski/videodownloader:latest
docker stop videodownloader
docker rm videodownloader
docker run -d \
--name videodownloader \
-p 8080:8080 \
-v ~/downloads:/app/downloads \
-v ~/yt-dlp-plugins:/app/yt-dlp-plugins \
-e APP_LANGUAGE=en \
-e YTDLP_CHANNEL=stable \
-e PYTHONPATH=/app/yt-dlp-plugins \
-e MAX_CONCURRENT_JOBS=2 \
-e MAX_DOWNLOAD_FILES=50 \
-e MAX_DOWNLOAD_AGE_HOURS=168 \
-e MAX_JOB_HISTORY=100 \
-e CLEANUP_INTERVAL_HOURS=1 \
-e HTTP_MAX_BODY_BYTES=1048576 \
-e HTTP_READ_TIMEOUT_SECONDS=15 \
-e HTTP_READ_HEADER_TIMEOUT_SECONDS=10 \
-e HTTP_WRITE_TIMEOUT_SECONDS=30 \
-e HTTP_IDLE_TIMEOUT_SECONDS=60 \
--restart unless-stopped \
marekotulakowski/videodownloader:latest
If you want to receive extractor fixes faster, change:
YTDLP_CHANNEL=stable
to:
YTDLP_CHANNEL=nightly
If you want files to disappear after 24 hours instead of the default 7 days, change:
MAX_DOWNLOAD_AGE_HOURS=168
to:
MAX_DOWNLOAD_AGE_HOURS=24
If you want to limit the total size of all saved materials, add for example:
MAX_DOWNLOAD_SIZE_MB=20480
This example means 20 GB. When that limit is reached, the app will stop accepting new saved files and show a message in the user's selected language asking them to remove some files from Downloaded files.
Prepare the host directories first:
mkdir -p ~/downloads ~/yt-dlp-plugins
sudo chown -R 999:999 ~/downloads ~/yt-dlp-plugins
Run the container:
docker run -d \
--name videodownloader \
-p 8080:8080 \
-v ~/downloads:/app/downloads \
-v ~/yt-dlp-plugins:/app/yt-dlp-plugins \
-e APP_LANGUAGE=en \
-e YTDLP_CHANNEL=stable \
-e PYTHONPATH=/app/yt-dlp-plugins \
-e MAX_CONCURRENT_JOBS=2 \
-e MAX_DOWNLOAD_FILES=50 \
-e MAX_DOWNLOAD_AGE_HOURS=168 \
-e MAX_JOB_HISTORY=100 \
-e CLEANUP_INTERVAL_HOURS=1 \
-e HTTP_MAX_BODY_BYTES=1048576 \
-e HTTP_READ_TIMEOUT_SECONDS=15 \
-e HTTP_READ_HEADER_TIMEOUT_SECONDS=10 \
-e HTTP_WRITE_TIMEOUT_SECONDS=30 \
-e HTTP_IDLE_TIMEOUT_SECONDS=60 \
--restart unless-stopped \
marekotulakowski/videodownloader:latest
Then open:
http://localhost:8080
services:
downloader:
image: marekotulakowski/videodownloader:latest
container_name: videodownloader
ports:
- "8080:8080"
environment:
APP_LANGUAGE: "en"
YTDLP_CHANNEL: "stable"
PYTHONPATH: "/app/yt-dlp-plugins"
MAX_CONCURRENT_JOBS: "2"
MAX_DOWNLOAD_FILES: "50"
MAX_DOWNLOAD_AGE_HOURS: "168"
MAX_JOB_HISTORY: "100"
CLEANUP_INTERVAL_HOURS: "1"
HTTP_MAX_BODY_BYTES: "1048576"
HTTP_READ_TIMEOUT_SECONDS: "15"
HTTP_READ_HEADER_TIMEOUT_SECONDS: "10"
HTTP_WRITE_TIMEOUT_SECONDS: "30"
HTTP_IDLE_TIMEOUT_SECONDS: "60"
volumes:
- ./downloads:/app/downloads
- ./yt-dlp-plugins:/app/yt-dlp-plugins
restart: unless-stopped
If you want a storage cap in Docker Compose, add for example:
MAX_DOWNLOAD_SIZE_MB: "20480"
Start it with:
docker compose up -d
server {
listen 80;
server_name example.com;
client_max_body_size 1m;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
/app/downloads, so mount that directory as a volumeCLEANUP_INTERVAL_HOURS168 hours; set MAX_DOWNLOAD_AGE_HOURS=24 for one-day retentionMAX_DOWNLOAD_SIZE_MB/app/yt-dlp-pluginsen, pl, de, esyt-dlpContent type
Image
Digest
sha256:9c98241f4…
Size
377.8 MB
Last updated
3 months ago
docker pull marekotulakowski/videodownloader