Rich CLI + web dashboard for grabbing albums and files from Bunkr with resilient retries, live progress, and container-ready deployment.
If you find this project useful, please consider giving it a star on GitHub! β
- Dual experience: Python CLI (
downloader.py,main.py) or a polished web dashboard powered by FastAPI. - Liquid-glass UI π: macOS Sonoma / iOS 17 aesthetic with
backdrop-filtervibrancy, OKLCH-based color tokens, an Auto / Light / Dark appearance menu that follows your OS, and WCAG-AA contrast in both modes. - Realtime feedback: Rich terminal UI and a websocket + polling hybrid on the web keep progress/logs alive, even after restarts.
- Concurrent + reliable π: Per-job network context isolates parallel downloads; monotonic event IDs with a WS β polling mutex prevent duplicate or missed progress updates across reconnects; progress bars converge to 100% (no more 99% stalls); sandboxed download root, bounded in-memory event log, optional bearer-token auth, and TTL-scoped job reaper keep long-running containers safe.
- Maintenance detection π: Real-time status page checks detect server maintenance and apply intelligent retry strategies with longer delays or skip affected files.
- Smart filtering: Include/ignore rules, disk-space guard, filename sanitisation, and album pagination handled automatically.
- Configurable storage: Point downloads to any folder (CLI
--custom-pathor web directory picker) with existing files skipped safely. - Container friendly: Multi-stage Docker image, docker-compose stack, and CI pipeline for publishing multi-arch images to GHCR.
Note/Advice: Use a VPN. Bunkr sometimes blocks your IP when you bulk download. While it gets unblocked after a while, its best to use this behind a VPN
v0.12.0 β June 2026
- Update notifications in the web UI: the dashboard now checks GitHub for newer releases and shows an "β update available: vX.Y.Z" badge directly under the version when your running build is out of date, linking straight to the Releases page.
- Light on GitHub: the check runs server-side and is cached (~6h), so all browser sessions share a single upstream request instead of each polling GitHub β and a GitHub hiccup simply shows no badge rather than erroring.
v0.11.5 β June 2026
- Security maintenance: cleared the open frontend security advisories β axios bumped to 1.16.1 (
GHSA-654m-c8p4-x5fp, Proxy-Authorization header injection via prototype pollution) and the build-time postcss to 8.5.15 (GHSA-qx2v-qp2m-jg93, CSS-stringify XSS).npm auditnow reports zero vulnerabilities.
v0.11.4 β June 2026
- Downloads work again: Bunkr retired the
/api/vsendpoint (it now returns 404 for every file) and switched to signed CDN URLs β item pages embed the raw CDN link plus a signing endpoint that issues a short-lived access token. The crawler was rewritten to follow this new flow, restoring album and single-file downloads. - SSRF hardening: the signing endpoint host is read from page content, so it is now validated (HTTPS + host allowlist) before any server-side request is made. Override the allowlist with
BUNKR_SIGN_ALLOWED_HOSTS(defaultcdn.cr) if Bunkr rotates its signing infrastructure.
See the Releases page for the full changelog.
This is the easiest way to run BunkrDownloader. You'll need Docker Desktop installed on your machine (or Docker Engine + Compose on Linux).
-
Prepare configuration: Create a
.envfile to customize your settings.cp .env.sample .env
Windows users: You can copy and rename the file in File Explorer.
-
Customize (Optional): Open
.envin a text editor to change where files are saved (DOWNLOADS_DIR) or which port to use (API_PORT). -
Start the application: Run the following command to download the image and start the service in the background:
docker compose up -d
Once running, open http://localhost:8000 in your browser.
- Stop:
docker compose down - Updates: Run
docker compose pullfollowed bydocker compose up -dto switch to the latest version. - Logs:
docker compose logs -f(Ctrl+C to exit).
You can configure the deployment by setting the following environment variables in your .env file.
| Variable | Description | Default Value |
|---|---|---|
API_PORT |
The host port to access the Web UI and API. | 8000 |
API_HOST |
The host address the application listens on. | 0.0.0.0 |
DOWNLOADS_DIR |
The local directory where files will be saved. | ./Downloads |
LOGS_DIR |
The local directory where logs will be stored. | ./logs |
SESSION_LOG_PATH |
The internal path for the session log. | /app/logs/session.log |
IMAGE_TAG |
The Docker image version tag to use (e.g., latest or 1.2.3). |
latest |
UID |
The user ID to run the container as. | 1000 |
GID |
The group ID to run the container as. | 1000 |
STATUS_CHECK_ON_FAILURE π |
Enable real-time status page checks on download failures. | true |
STATUS_CACHE_TTL_SECONDS π |
Cache duration for status page results in seconds. | 60 |
MAINTENANCE_RETRY_STRATEGY π |
Strategy for maintenance: backoff (retry with delays) or skip (log and skip). |
backoff |
ALLOWED_DOWNLOAD_ROOT π |
Filesystem root that incoming custom_path and /api/directories?basePath values must resolve under. Rejects any path that escapes this root with HTTP 422. Set to / to disable sandboxing (not recommended for public-facing deployments). |
<cwd>/Downloads |
API_ACCESS_TOKEN π |
Shared bearer token. When set, every /api/* request must carry Authorization: Bearer <token> and every /ws/* connection must include ?token=<token>. When unset, the API is unauthenticated and a warning is logged on startup β safe only on a trusted LAN. |
(unset) |
ALLOWED_ORIGINS π |
Comma-separated list of CORS-allowed origins (e.g. https://dash.example.com,https://admin.example.com). Takes precedence over ALLOWED_ORIGIN_REGEX when set. |
(unset) |
ALLOWED_ORIGIN_REGEX π |
Regex fallback for CORS when ALLOWED_ORIGINS is unset. The default covers Vite dev-server and uvicorn on localhost. |
https?://(localhost|127\.0\.0\.1)(:\d+)? |
JOB_EVENT_RETENTION π |
Maximum number of events retained per job in the in-memory ring buffer. Clients whose cursor falls below the retained floor get a 410 Gone so they can reset rather than silently missing history. |
2000 |
JOB_TTL_HOURS π |
Terminal jobs (completed / failed / cancelled) older than this are evicted by the background reaper so long-running containers don't grow unbounded. | 24 |
JOB_REAPER_INTERVAL_SECONDS π |
How often the reaper scans for stale terminal jobs. | 900 |
BUNKR_SIGN_ALLOWED_HOSTS π |
Comma-separated allowlist of hosts the page-declared media signing endpoint may use (SSRF guard). A candidate matches when it equals an entry or is a subdomain of one, and only HTTPS is accepted. Override when Bunkr rotates its signing infrastructure off cdn.cr. |
cdn.cr |
Set IMAGE_TAG to a published semantic version (for example 1.2.3) if you want to pin a specific release; otherwise latest is used.
# Backend
pip install -r requirements.txt
uvicorn src.web.app:app --reload
# Frontend (optional live dev server)
cd frontend
npm install
npm run devThe Vite dev server proxies API/WebSocket traffic to http://localhost:8000 by default. Run npm run build once to bake a production bundle served by FastAPI.
# Single URL
python3 downloader.py <bunkr_url> [--include term ...] [--ignore term ...] [--custom-path /path] [--disable-ui] [--disable-disk-check] [--skip-status-check] [--maintenance-strategy backoff|skip] [--status-cache-ttl SECONDS]
# Batch mode (URLs.txt)
python3 main.py [shared flags]--includedownloads files containing any supplied substring.--ignoreskips files containing any supplied substring.--custom-pathpoints downloads to<path>/Downloads.--disable-uiswaps the Rich interface for plain logging (useful in notebooks/CI).--skip-status-checkπ disables real-time status page checks on download failures (defaults to enabled).--status-cache-ttl SECONDSπ controls cache duration for status page results (default: 60s).--maintenance-strategy backoff|skipπ chooses retry behavior:backoffretries with longer delays (2min, 5min, 10min),skiplogs and skips maintenance files.
- Job launcher β paste URLs, set filters, toggle the disk check, or choose a custom destination via the directory browser.
- Progress panes β overall progress + per-file stripes; tooltips explain each control and metric.
- Live log β chronological events, retries, and skips with full timestamps.
- Resilient updates β when a WebSocket drops (e.g. container restart) the UI polls
/api/downloads/{job}/eventsuntil the socket reconnects. - Source shortcut β in-app link to the GitHub repository for quick reference.
- Version badge β header shows the semantic version embedded in the running container image.
.env(tracked example) controls container defaults:API_HOST,API_PORT,DOWNLOADS_DIR, plus Vite proxy hints (VITE_*).- Web UI tooltips describe every form element; hover to see accepted formats and side effects.
- Downloads default to
Downloads/in the working directory unlesscustom_path(CLI) or the directory picker overrides it. session.logpersists problematic URLs so you can retry them later. π Maintenance events are logged with format:[MAINTENANCE] timestamp | subdomain | status | url.
downloader.py/main.pycallvalidate_and_download, which builds aSessionInfoand streams progress viaLiveManager.src/web/app.pywraps the same flow:JobEventBrokerbuffers events,WebLiveManagermirrors CLI progress/log calls, and FastAPI exposes REST + WebSocket endpoints.src/crawlers/*resolve album pagination, decrypt media URLs, and normalise filenames.src/downloaders/*handle concurrency, retries, and chunked writes throughdownload_utils.save_file_with_progress; subdomain outages are tracked withbunkr_utils.- π Maintenance detection:
bunkr_utils.refresh_server_statuschecks Bunkr's status page on download failures with TTL-based caching. Failed downloads are grouped by subdomain and rechecked before final retries. frontend/src/App.jsxconsumes/api/downloads,/api/directories,/ws/jobs/{id}, and the/api/downloads/{id}/eventspolling fallback for seamless updates. π Maintenance events trigger toast notifications.
- Python β₯ 3.10, Node β₯ 18 recommended.
- Activate the virtualenv and lint with
python -m pylint $(git ls-files '*.py'); resolve any findings before committing. - Run
python -m compileall srcandnpm run buildbefore opening a PR to catch syntax/bundle issues. docker compose up --buildexercises the full stack locally using the tracked.env.- Use
session.logand the web log pane to inspect failed URLs or storage issues.
- Start with the guidelines in
CONTRIBUTING.mdfor branching, linting, and smoke-test expectations. - Prefer Conventional Commits (
feat:,fix:,docs:, etc.) so semantic-release can generate changelogs correctly. - Include the manual checks you ran (lint,
compileall,npm run build, CLI/Web smoke tests) in your pull request description. - Keep your branch rebased on
mainand respond quickly to review feedback to keep the release pipeline flowing.
- Open a new issue from the repositoryβs Issues β New issue page; choose the Bug report template for defects or the Feature request template for enhancements.
- The templates collect environment details (OS, Python version, tool version) and walk you through logs, reproduction steps, and desired outcomes so maintainers can triage quickly.
- Always confirm youβre running the latest release from GitHub Releases and search for duplicates before filing.
- Blank issues are disabled, so pick the template thatβs closest to your situation and use the βAdditional contextβ field to capture anything extra.
This project is a fork of Lysagxra/BunkrDownloader. However, it has been heavily refactored and modified for a web dashboard interface and other enhancements including dockerizing the application.
MIT License Β© tekgnosis-net
