No description
Find a file
xpltd 1592407658 First-run admin setup wizard, password persistence, forced setup gate
- Admin enabled by default (was opt-in via env var)
- New /admin/status (public) and /admin/setup (first-run only) endpoints
- Setup endpoint locked after first use (returns 403)
- Admin password persisted to SQLite config table (survives restarts)
- Change password now persists to DB (was in-memory only)
- Frontend router guard forces /admin redirect until setup is complete
- AdminSetup.vue wizard: username + password + confirm
- Public config exposes admin_enabled/admin_setup_complete for frontend
- TLS warning only fires when password is actually configured
2026-03-21 20:01:13 -05:00
.bg-shell chore(M001/S01/T02): auto-commit after execute-task 2026-03-17 22:41:58 -05:00
.claude GSD: S02 complete — SSE transport, session system, health/config endpoints 2026-03-18 18:37:35 -05:00
.github/workflows v1.0.0: Fix Docker refs, Caddyfile, dedupe CI, add LICENSE 2026-03-19 07:26:11 -05:00
.gsd Docker self-hosting: fix persistence, add data_dir config 2026-03-19 09:56:10 -05:00
.planning docs: complete project research 2026-03-17 21:36:25 -05:00
backend First-run admin setup wizard, password persistence, forced setup gate 2026-03-21 20:01:13 -05:00
frontend First-run admin setup wizard, password persistence, forced setup gate 2026-03-21 20:01:13 -05:00
.dockerignore Docker self-hosting: fix persistence, add data_dir config 2026-03-19 09:56:10 -05:00
.env.example Docker self-hosting: fix persistence, add data_dir config 2026-03-19 09:56:10 -05:00
.gitignore chore: init gsd 2026-03-17 21:43:36 -05:00
Caddyfile v1.0.0: Fix Docker refs, Caddyfile, dedupe CI, add LICENSE 2026-03-19 07:26:11 -05:00
Caddyfile.example R021/R022/R026: Docker, CI/CD, deployment example 2026-03-19 06:57:25 -05:00
DEPLOY-TEST-PROMPT.md Persistent admin settings + new server config fields 2026-03-19 12:11:53 -05:00
docker-compose.example.yml Docker self-hosting: fix persistence, add data_dir config 2026-03-19 09:56:10 -05:00
docker-compose.yml Docker self-hosting: fix persistence, add data_dir config 2026-03-19 09:56:10 -05:00
Dockerfile Fix SSE busy-loop (ping=0), keep curl in image, recover zombie jobs on startup 2026-03-21 17:59:24 -05:00
LICENSE v1.0.0: Fix Docker refs, Caddyfile, dedupe CI, add LICENSE 2026-03-19 07:26:11 -05:00
PROJECT.md chore: checkpoint v1 GSD research artifacts before migrating to GSDv2 2026-03-17 21:40:37 -05:00
README.md Docker self-hosting: fix persistence, add data_dir config 2026-03-19 09:56:10 -05:00

media.rip()

A self-hostable yt-dlp web frontend. Paste a URL, pick quality, download — with session isolation, real-time progress, and a cyberpunk default theme.

License Docker

Features

  • Paste & download — Any URL yt-dlp supports. Format picker with live quality extraction.
  • Real-time progress — Server-Sent Events stream download progress to the browser instantly.
  • Session isolation — Each browser gets its own download queue. No cross-talk.
  • Playlist support — Collapsible parent/child jobs with per-video status tracking.
  • Three built-in themes — Cyberpunk (default), Dark, Light. Switch in the header.
  • Custom themes — Drop a CSS file into /themes volume. No rebuild needed.
  • Admin panel — Session management, storage info, manual purge, error logs. Protected by bcrypt auth.
  • Cookie auth — Upload cookies.txt per session for paywalled/private content.
  • Auto-purge — Configurable scheduled cleanup of old downloads and logs.
  • Zero telemetry — No outbound requests. No CDN, no fonts, no analytics. CSP enforced.
  • Mobile-friendly — Responsive layout with bottom tabs on small screens.

Quickstart

docker compose up

Open http://localhost:8080 and paste a URL.

Downloads are saved to ./downloads/.

Docker Volumes

Mount Purpose Persists
/downloads Downloaded media files Bind mount recommended
/data SQLite database, session cookies, error logs Named volume recommended
/themes Custom theme CSS overrides (optional) Read-only bind mount
/app/config.yaml YAML config file (optional) Read-only bind mount

Important: The /data volume contains the database (download history, admin state, error logs) and session cookie files. Use a named volume or bind mount to persist across container restarts.

Configuration

All settings have sensible defaults. Override via environment variables or config.yaml:

Variable Default Description
MEDIARIP__SERVER__PORT 8000 Internal server port
MEDIARIP__SERVER__DB_PATH /data/mediarip.db SQLite database path
MEDIARIP__SERVER__DATA_DIR /data Persistent data directory
MEDIARIP__DOWNLOADS__OUTPUT_DIR /downloads Where files are saved
MEDIARIP__DOWNLOADS__MAX_CONCURRENT 3 Maximum parallel downloads
MEDIARIP__SESSION__MODE isolated isolated, shared, or open
MEDIARIP__SESSION__TIMEOUT_HOURS 72 Session cookie lifetime
MEDIARIP__ADMIN__ENABLED false Enable admin panel
MEDIARIP__ADMIN__USERNAME admin Admin username
MEDIARIP__ADMIN__PASSWORD_HASH (empty) Bcrypt hash of admin password
MEDIARIP__PURGE__ENABLED false Enable auto-purge of old downloads
MEDIARIP__PURGE__MAX_AGE_HOURS 168 Delete downloads older than this
MEDIARIP__PURGE__CRON 0 3 * * * Purge schedule (cron syntax)
MEDIARIP__THEMES_DIR /themes Custom themes directory

Session Modes

  • isolated (default): Each browser session has its own private queue.
  • shared: All sessions see all downloads. Good for household/team use.
  • open: No session tracking at all.

Admin Panel

Enable the admin panel to manage sessions, view storage, trigger manual purge, and review error logs:

# docker-compose.yml environment section
MEDIARIP__ADMIN__ENABLED: "true"
MEDIARIP__ADMIN__USERNAME: "admin"
MEDIARIP__ADMIN__PASSWORD_HASH: "$2b$12$..."  # see below

Generate a bcrypt password hash:

docker run --rm python:3.12-slim python -c \
  "import bcrypt; print(bcrypt.hashpw(b'YOUR_PASSWORD', bcrypt.gensalt()).decode())"

Admin state (login, settings changes) persists in the SQLite database at /data/mediarip.db.

Custom Themes

  1. Create a folder in your themes volume: ./themes/my-theme/
  2. Add metadata.json:
    { "name": "My Theme", "author": "You", "description": "A cool theme" }
    
  3. Add theme.css with CSS variable overrides:
    [data-theme="my-theme"] {
      --color-bg: #1a1a2e;
      --color-accent: #e94560;
      /* See base.css for all 50+ tokens */
    }
    
  4. Restart the container. Your theme appears in the picker.

See the built-in themes in frontend/src/themes/ for fully commented examples.

Secure Deployment

For production with TLS, use the included Caddy reverse proxy:

cp docker-compose.example.yml docker-compose.yml
cp .env.example .env
# Edit .env with your domain and admin password hash
docker compose up -d

Caddy automatically provisions Let's Encrypt TLS certificates for your domain.

Development

Backend

cd backend
python -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/pip install pytest pytest-asyncio pytest-anyio httpx ruff
.venv/bin/python -m pytest tests/ -v -m "not integration"

Frontend

cd frontend
npm install
npm run dev       # Dev server with hot reload
npx vitest run    # Run tests
npm run build     # Production build

API

Endpoint Method Description
/api/health GET Health check with version + uptime
/api/config/public GET Public configuration
/api/downloads GET List downloads for current session
/api/downloads POST Start a new download
/api/downloads/{id} DELETE Cancel/remove a download
/api/formats GET Extract available formats for a URL
/api/events GET SSE stream for real-time progress
/api/cookies POST Upload cookies.txt for authenticated downloads
/api/cookies DELETE Remove cookies.txt for current session
/api/themes GET List available custom themes
/api/admin/* GET/POST Admin endpoints (requires auth)

Architecture

  • Backend: Python 3.12 + FastAPI + aiosqlite + yt-dlp
  • Frontend: Vue 3 + TypeScript + Pinia + Vite
  • Transport: Server-Sent Events for real-time progress
  • Database: SQLite with WAL mode
  • Styling: CSS custom properties (no Tailwind, no component library)
  • Container: Multi-stage build, non-root user, amd64 + arm64

License

MIT