- Python 37.1%
- JavaScript 24.7%
- CSS 20.2%
- HTML 12%
- Just 4.8%
- Other 1.2%
|
All checks were successful
Build and publish Docker image / build-and-push (push) Successful in 2m4s
Co-authored-by: PatillaCode <patillacode@gmail.com> Co-committed-by: PatillaCode <patillacode@gmail.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| app | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| justfile | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
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=falseto 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.