Na domácím serveru provozuji běžné věci z homelabu: zálohy, média a občas i "stáhnu si to teď a roztřídím později". Dlouho jsem na to používal JDownloader2. Je to silný a osvědčený nástroj, který řeší spoustu reálných problémů.
Moje konkrétní nasazení ale bylo nepohodlné. JDownloader2 běžel v Dockeru na serveru a já ho ovládal přes VNC v prohlížeči. Fungovalo to, ale jednoduché věci působily zbytečně těžkopádně. Sdílení schránky bylo dvoufázové, měnění velikosti desktopového UI v prohlížeči nikdy nebylo příjemné, na mobilu to bylo téměř nepoužitelné a přidávání odkazů z CLI znamenalo opřít se o MyJDownloader s online účtem. To jsem pro server v racku nechtěl.
Postupně mi došlo, že nepotřebuji download manager, který se tváří jako desktopová aplikace. Potřebuji malou službu, která vystaví perzistentní frontu.
Tak vzniklo DLQ (Download Queue): headless download-queue daemon a CLI, inspirované tou částí JDownloaderu, kterou jsem opravdu potřeboval, ale navržené pro Docker, SSH, terminál a domácí server workflow. Zároveň jsem chtěl reálnou záminku naučit se Go a SvelteKit, takže Go skončilo jako jazyk daemonu/CLI a SvelteKit jako volitelné web UI.
Repo projektu: github.com/Witriol/dlq-download-queue
Co DLQ je
DLQ je záměrně užší než JDownloader2. Nesnaží se být univerzální download manager s obrovským plugin ekosystémem, captcha workflow, hlubokým link grabbingem a desktopovou automatizací. Cíl je smyčka, kterou na serveru opravdu potřebuji: přidat odkazy, udržet frontu přes restarty, spustit stahování, vidět chyby, čistě retryovat a ukládat soubory do známých připojených složek.
Jádro je dlqd, Go daemon s HTTP API na portu 8099 by default. Ukládá joby do SQLite, resolvuje URL a samotné stahování deleguje na aria2 přes JSON-RPC. CLI klient dlq mluví se stejným API, takže frontu jde ovládat ze SSH skriptů, cron-like workflow i interaktivního terminálu. Volitelný dlq-webui container běží jako SvelteKit UI na portu 8098 a server-side proxyuje API volání.
Zjednodušeně to vypadá takto:
Prohlížeč
-> dlq-webui (:8098)
-> dlqd API (:8099) <- dlq CLI
-> resolver
-> queue service
- SQLite (/state/dlq.db)
- události/logy
-> aria2 RPC
-> /data
Nejdůležitější návrhové rozhodnutí je perzistence. Job není jen aria2 proces; je to řádek ve frontě se stavem, počtem pokusů, výstupní složkou, resolver metadaty, filename, událostmi a dostatkem historie, aby šlo později odpovědět na otázku "co se stalo?". Když se server restartuje, fronta zůstane. Když stahování selže, můžu se podívat na události jobu místo hádání z napůl zapomenuté desktop session.
Jak se chová
Z CLI je běžné workflow záměrně malé:
# Přidat job
docker exec -it dlq dlq add "<url>" --out /data/downloads
# Sledovat frontu
docker exec -it dlq dlq status --watch
# Prohlédnout chyby
docker exec -it dlq dlq logs 12 --tail 80
Joby jdou pozastavit nebo obnovit, retryovat, soft-deleteovat, vypsat i se smazanými položkami a filtrovat podle stavu. DLQ sleduje jasné stavové přechody jako queued, resolving, downloading, paused, decrypting, completed, failed a decrypt_failed. U Webshare jobů se pause/resume navenek chová spíš jako stop/retry, protože starý transfer state bývá méně užitečný než čerstvě resolvovaný link.
Resolvery jsou pluggable. Aktuální sada obsahuje jednoduchý HTTP/HTTPS passthrough, Webshare anonymous mode a veřejné MEGA file linky. Chyby resolverů mají být konkrétní: login_required, quota_exceeded, captcha_needed, temporarily_unavailable a unknown_site jsou mnohem užitečnější než vágní "nestáhlo se to".
Post-processing se stal větší částí projektu, než jsem původně čekal. DLQ umí po úspěšném stažení spustit archive decrypt/extract, ukládá archive password per add batch, maskuje citlivé hodnoty v logách a selhanou extrakci přesune do samostatného stavu decrypt_failed. MEGA linky mají vlastní post-download payload decryption s integrity verification. Multipart archivy se seskupují, takže .partNN.rar a starší .rar / .r00 sady jde retryovat nebo odstranit jako celek, místo abych musel řešit každý part zvlášť.
Docker, UI a hranice
DLQ je Docker-first, protože takhle podobné služby doma provozuji. Daemon validuje out_dir vůči nakonfigurovaným DATA_* mountům, takže joby mohou zapisovat jen tam, kam bylo úložiště explicitně připojené. Stejné DATA_* hodnoty se v API a UI promění na destination presets, což se hodí hlavně na Unraidu, kde služba může mít připojených několik media složek do různých container paths.
Web UI není střed systému. Je to komfortní vrstva pro batch adds, procházení cílových složek, označení oblíbených výstupních adresářů, sledování seskupených jobů, změnu runtime settings a kontrolu logů ze zařízení, kde SSH není pohodlné. CLI i UI mluví se stejným daemonem, takže workflow nevlastní ani jedno z nich.
Bezpečnost je záměrně přímočará: DLQ je pro důvěryhodné sítě, typicky domácí LAN nebo Docker network. API nemá autentizaci, takže :8099 nepatří přímo na internet. Pokud je potřeba vzdálený přístup, má být za reverse proxy s autentizací. aria2 by také mělo mít ARIA2_SECRET, protože jeho JSON-RPC endpoint je součást runtime.
aria2 jsem vybral proto, že jsem nechtěl znovu implementovat spolehlivé stahování souborů. Umí resume, paralelismus, progress i reporting. DLQ se soustředí na orchestraci: perzistentní stav fronty, retry chování, resolver-specific handling, bezpečnost výstupních cest a post-processing.
Aktuální stav
První verze byla hlavně malý daemon, CLI, SQLite fronta, aria2 integrace a Webshare resolver. Od té doby se projekt dost přiblížil nástroji, který jsem chtěl používat: volitelné SvelteKit UI, MEGA support, archive extraction, multipart archive grouping, folder favorites, runtime settings, Unraid deploy skripty a jasnější mapování chyb.
Pořád se nesnaží nahradit všechny části JDownloader2. To je pointa. JDownloader2 je pořád lepší odpověď, pokud někdo potřebuje široký desktopový download manager s velkým plugin ekosystémem. DLQ je lepší fit pro můj užší případ: scriptovatelná, pozorovatelná, Docker-native fronta na domácím serveru.
Jako learning projekt se trefil do správné velikosti. Go dávalo smysl pro daemon a CLI: jedna malá binárka, přímočará konkurence a praktická HTTP služba. SvelteKit fungoval dobře pro tenký dashboard, který hlavně proxyuje API volání a vykresluje aktuální stav fronty. Výsledek není univerzální download impérium, ale nahradil VNC-driven workflow, které mě už nebavilo používat.