No description
  • HTML 63.1%
  • JavaScript 35.9%
  • Dockerfile 1%
Find a file
Lars 3933782ba9 feat: integrate yt-dlp utilities, fix YouTube downloads, revamp UI
- Extract ytdlp.js with sanitizeUrl, isPlaylistUrl, parseYtDlpJson, and
  scheduled auto-update (every 24h, first check after 5m)
- Fix YouTube n-challenge: add --js-runtimes node and --ignore-config to
  all yt-dlp invocations; yt-dlp[default] bundles EJS scripts
- Fix format selection: detect preset selector strings vs numeric IDs to
  avoid double-wrapping format args
- Guard cookies.txt: only pass --cookies if file is non-empty
- Add playlist URL rejection in /api/info
- Unify UI: login.html now shares the same design system as index.html
  (fonts, CSS variables, card style, background grid)
- Add sign-out confirmation modal with CSRF-POST flow
- Overhaul README: add cookies, reverse proxy, and auto-update docs
- Tighten .gitignore and .dockerignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 02:45:09 +02:00
.github/workflows Add Docker publish workflow 2026-03-29 17:12:54 +02:00
public feat: integrate yt-dlp utilities, fix YouTube downloads, revamp UI 2026-04-04 02:45:09 +02:00
tests fix: use req.originalUrl in requireAuth, fix misleading comment in routes.test.js 2026-04-03 14:27:00 +02:00
.dockerignore feat: integrate yt-dlp utilities, fix YouTube downloads, revamp UI 2026-04-04 02:45:09 +02:00
.env.example fix: add AUTH_URL env var for reverse proxy deployments 2026-04-03 18:19:03 +02:00
.gitignore feat: integrate yt-dlp utilities, fix YouTube downloads, revamp UI 2026-04-04 02:45:09 +02:00
auth.js debug: add Auth.js logger to surface errors in docker logs 2026-04-03 18:10:52 +02:00
docker-compose-build.yml chore: remove server-specific Traefik labels from compose file 2026-04-03 18:38:10 +02:00
docker-compose.yml feat: integrate yt-dlp utilities, fix YouTube downloads, revamp UI 2026-04-04 02:45:09 +02:00
Dockerfile feat: integrate yt-dlp utilities, fix YouTube downloads, revamp UI 2026-04-04 02:45:09 +02:00
package-lock.json chore: convert to ESM, add @auth/express and Vitest 2026-04-03 14:09:07 +02:00
package.json chore: convert to ESM, add @auth/express and Vitest 2026-04-03 14:09:07 +02:00
README.md feat: integrate yt-dlp utilities, fix YouTube downloads, revamp UI 2026-04-04 02:45:09 +02:00
server.js feat: integrate yt-dlp utilities, fix YouTube downloads, revamp UI 2026-04-04 02:45:09 +02:00
vitest.config.js feat: add Auth.js middleware and requireAuth route protection 2026-04-03 14:24:12 +02:00
ytdlp.js feat: integrate yt-dlp utilities, fix YouTube downloads, revamp UI 2026-04-04 02:45:09 +02:00

FETCH — yt-dlp Web UI

A self-hosted video downloader with a clean web UI, powered by yt-dlp. Runs as a Docker container with OAuth authentication.

Supports YouTube, Vimeo, TikTok, Twitter/X, and 1000+ other sites.

Warning

This repo has been heavily generated with Claude.

Requirements

  • Docker + Docker Compose
  • At least one OAuth provider configured (GitHub, Google, or Authentik)

Everything else (Node.js, yt-dlp, ffmpeg, Python) is inside the image.

Quick start

cp .env.example .env
# Edit .env — add AUTH_SECRET and at least one OAuth provider

docker compose up -d
# App is at http://localhost:4242

Authentication

All routes require login. AUTH_SECRET is always required.

# Generate AUTH_SECRET
openssl rand -base64 32
Provider Required env vars Register at
GitHub GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET github.com/settings/developers
Google GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET console.cloud.google.com/apis/credentials
Authentik AUTHENTIK_CLIENT_ID, AUTHENTIK_CLIENT_SECRET, AUTHENTIK_ISSUER Your Authentik instance

Set the OAuth callback URL to: https://your-domain/auth/callback/<provider>

YouTube cookies

YouTube requires authentication cookies to serve video formats (bot detection).

  1. Install the "Get cookies.txt LOCALLY" browser extension
  2. Go to youtube.com while logged in, export cookies in Netscape format
  3. Save the file as cookies.txt next to docker-compose.yml

The file is mounted at /app/cookies.txt — yt-dlp picks it up automatically. Without it, YouTube downloads will fail. Cookies expire periodically and will need re-exporting.

Reverse proxy

When running behind a reverse proxy (Traefik, nginx, etc.), set in .env:

AUTH_URL=https://your-domain
AUTH_TRUST_HOST=true

docker-compose-build.yml includes pre-configured Traefik labels as a reference.

Commands

docker compose up -d              # Start
docker compose down               # Stop
docker compose logs -f            # Follow logs
docker compose up --build -d      # Rebuild after code changes

yt-dlp auto-updates inside the container every 24 hours (first check 5 minutes after startup).

Development

npm install
npm start        # Runs on http://localhost:4242

npm test         # Run tests once
npm run test:watch

Note: local dev won't have yt-dlp or ffmpeg unless installed on the host. Docker is the recommended way to run this.

Notes

  • Downloaded files land in ./downloads on the host (mounted into the container)
  • Files expire and are cleaned up 10 minutes after download
  • To change the port, edit "4242:4242" in docker-compose.yml