Self-hosted web UI for downloading videos and audio via yt-dlp https://lasso.patilla.es
  • Python 37.1%
  • JavaScript 24.7%
  • CSS 20.2%
  • HTML 12%
  • Just 4.8%
  • Other 1.2%
Find a file
PatillaCode 785e2e5472
All checks were successful
Build and publish Docker image / build-and-push (push) Successful in 2m4s
password-management (#1)
Co-authored-by: PatillaCode <patillacode@gmail.com>
Co-committed-by: PatillaCode <patillacode@gmail.com>
2026-04-03 18:07:07 +02:00
.forgejo/workflows fix: use bash shell for tag derivation step 2026-04-03 04:33:03 +02:00
app password-management (#1) 2026-04-03 18:07:07 +02:00
.env.example password-management (#1) 2026-04-03 18:07:07 +02:00
.gitignore password-management (#1) 2026-04-03 18:07:07 +02:00
docker-compose.yml password-management (#1) 2026-04-03 18:07:07 +02:00
Dockerfile fix CI (IV) 2026-04-03 03:12:41 +02:00
justfile password-management (#1) 2026-04-03 18:07:07 +02:00
pyproject.toml password-management (#1) 2026-04-03 18:07:07 +02:00
README.md password-management (#1) 2026-04-03 18:07:07 +02:00
uv.lock password-management (#1) 2026-04-03 18:07:07 +02:00

lasso

A self-hosted web UI for downloading videos and audio from YouTube and hundreds of other sites — powered by yt-dlp.


Features

  • Download video — H.264/AAC MP4, natively playable on macOS and Windows
  • Download audio — extracted as MP3 at 192 kbps
  • Clip — fetch a video, preview it in-browser, set start/end times, download the trimmed clip
  • Session dashboard — tracks your downloads for the current session with TTL countdown
  • Deduplication — re-submitting the same URL skips re-downloading
  • Password protection — optional login gate with multiple named guest passwords, managed via a built-in admin UI
  • Auto-cleanup — temporary files removed after a configurable TTL (default 30 min)
  • Non-root Docker container — safe to self-host

Quick start (one command)

mkdir -p downloads data && chown 1000:1000 data
docker run -p 8080:8080 \
  -e ADMIN_PASSWORD=secret \
  -e SECRET_KEY=$(openssl rand -hex 32) \
  -e DOWNLOAD_DIR=/tmp/lasso \
  -v ./downloads:/tmp/lasso \
  -v ./data:/app/data \
  forgejo.patilla.es/patillacode/lasso:latest

Open http://localhost:8080, log in with your admin password, then visit /admin to add guest passwords.

No password prompt? Set PASSWORD_PROTECTED=false to skip the login gate entirely.


Self-hosting with Docker Compose

1. Create a folder and set up your environment

mkdir lasso && cd lasso
curl -O https://forgejo.patilla.es/patillacode/lasso/raw/branch/main/.env.example
curl -O https://forgejo.patilla.es/patillacode/lasso/raw/branch/main/docker-compose.yml
cp .env.example .env

2. Edit .env

PASSWORD_PROTECTED=true
ADMIN_PASSWORD=your-strong-password-here
SECRET_KEY=run-openssl-rand-hex-32-and-paste-here

Generate a secure SECRET_KEY:

openssl rand -hex 32

3. Create the data folder

mkdir -p data && chown 1000:1000 data

The container runs as uid 1000. This folder stores guest passwords (data/passwords.json) and persists across restarts via the ./data:/app/data volume mount in docker-compose.yml.

4. Start

docker compose up -d

Open http://localhost:8080. Log in with your ADMIN_PASSWORD, then go to /admin to add and manage guest passwords.

Downloaded files appear in a downloads/ folder next to your docker-compose.yml — no digging through Docker internals.

4. Update to the latest version

docker compose pull
docker compose up -d --force-recreate

Downloaded files

Files are stored in ./downloads/ (a folder created next to your docker-compose.yml). Each job gets its own subdirectory named by job ID. Files are automatically deleted after FILE_TTL_MINUTES minutes (default: 30).

Migrating from an older named volume

If you ran lasso before this bind-mount setup, your files are in a Docker-managed named volume:

# Find the volume
docker volume ls

# See where it lives on disk
docker volume inspect lasso_downloads
# look for the "Mountpoint" field — files are in that path

CI / releases

The Docker image is built and pushed automatically to forgejo.patilla.es/patillacode/lasso on every push to main (tagged :latest) and on every v* tag (tagged with the version number).

To cut a release:

just release 1.2.3  # tags v1.2.3, pushes — CI publishes the versioned image

Local development

Requirements: Python 3.12+, uv, ffmpeg

git clone https://forgejo.patilla.es/patillacode/lasso
cd lasso
just install   # installs deps + creates .env from example
# edit .env
just dev       # starts dev server on :8080 with hot reload

Environment variables

Variable Default Description
PASSWORD_PROTECTED true Enable the login gate
ADMIN_PASSWORD (required if protected) Admin credential — grants access to /admin to manage guest passwords
PASSWORDS_FILE data/passwords.json Path to the guest password store (label → bcrypt hash)
SECRET_KEY change-me-in-production Signs session cookies — use a long random value in production
DOWNLOAD_DIR /tmp/lasso Where temp files are stored inside the container
MAX_CONCURRENT_DOWNLOADS 2 Max parallel yt-dlp processes
FILE_TTL_MINUTES 30 Minutes before files are auto-deleted
PORT 8080 HTTP listen port

Recipes (just)

If you have just installed:

just install        # first-time setup: install deps + create .env
just dev            # run dev server with hot reload

just build          # build Docker image locally
just run            # build + run a single local container

just up             # pull latest image + docker compose up -d
just down           # docker compose down
just logs           # tail container logs
just restart        # pull latest image + restart containers

just release 1.2.3  # tag v1.2.3 and push — triggers CI to publish the image

just clean          # remove Python build artefacts
just clean-docker   # remove local Docker image and volumes

Supported sites

lasso uses yt-dlp under the hood, which supports 1,000+ sites including YouTube, Twitter/X, Instagram, Vimeo, SoundCloud, Twitch, and many more.

Full list: yt-dlp supported sites


Notes

  • Videos are downloaded as H.264/AAC MP4 — natively playable on macOS (QuickLook, QuickTime) and Windows without extra codecs.
  • Clipping uses ffmpeg -c copy (no re-encode), so it's near-instant.
  • The session dashboard lives in your browser's sessionStorage — it clears when you close the tab.
  • This tool is intended for personal use. Respect copyright law and the terms of service of the sites you download from.