2026-06-27 Manga Stack (Suwayomi + Komga + KOMF)
What I set out to do
Add manga management to the media-stack. Started open-ended (“what should I add for books/comics/manga?”), narrowed to manga first because it reuses the existing Flaresolverr, then built it end-to-end: research → draft → test → orchestrate → PR → merge → deploy. Tracked in Add Manga Stack to Media Stack.
What I actually did
- Research. Compared the books/comics/manga landscape. Key realization: the three are separate pipelines. Books = Readarr-fork + rreading-glasses (Readarr is dead) or Calibre-Web-Automated; comics = Mylar3/Kapowarr; manga = Suwayomi (Mihon extensions), which does not use Prowlarr/qBittorrent at all. Picked manga first.
- Built three services: Suwayomi (downloader → CBZ+ComicInfo.xml into
${MEDIA_DIR}/manga, direct port 4567), Komga (reader under nginx/komga), KOMF (AniList/MangaUpdates metadata). Wrotesetup-komga.shfor the orchestrator. - Live-tested at every step rather than trusting the draft. This caught a string of real bugs before they shipped (below).
- Shipped PR #36, addressed five rounds of AI review, squash-merged (
5126644).
What was striking
The bugs only surfaced because I ran the containers, not because I read the code:
- Suwayomi
EXTENSION_REPOSmust be a HOCON array literal — a bare URL crashes the config parser on the:. - KOMF crash-loops without a committed
application.yml. - Komga claim API (
POST /api/v1/claim) bootstraps the admin headlessly — turned a “manual first-boot UI step” into a zero-manual flow. - Two
setup-komga.shbugs:jq '.isClaimed // empty'swallows booleanfalse(and a missing key prints the string"null"); and a global$http_codeset inside a$(...)subshell never escaped it, silently masking non-2xx responses.
And the meta-lesson on AI review: it regenerates on every push and ships occasional false “deploy-breaking” claims — review #5’s “gotson/komga has no curl” was wrong (verified /usr/bin/curl + {"status":"UP"} in-container), and review #1’s “every other service is pinned” was false (the stack is :latest + Watchtower). The user caught the second one before I did. Verify empirically; don’t accept a reviewer’s premise.
What’s left
- Live deploy on the box (set
KOMGA_EMAIL/KOMGA_PASSWORD,mstack,docker compose up -d). - The one path not yet exercised: a real chapter flowing Suwayomi → disk → Komga index.
Related
Add Manga Stack to Media Stack · Homelab Services Architecture · Media Stack IaC Declarative Config Evaluation
Follow-up session — declarative sources + covers (PR #39)
After the smoke test, two refinements to make sources and covers declarative, then merged + redeployed.
- Series cover was blank. KOMF was applying metadata (summary/genres/status) but never a poster. Root cause: I’d put the
metadataUpdateblock at the top level ofapplication.yml; KOMF only honors it nested underkomga:(komga.metadataUpdate.default.seriesCovers). Top-level is silently ignored — metadata updates, no cover. After nesting +overrideExistingCovers: true, re-matching One Piece (POST /komga/match/library/{id}/series/{id}on KOMF port 8085, internal-only) uploaded the real MangaUpdates poster (255×400USER_UPLOADED, selected). - Declarative source installs. Extended
setup-suwayomi.shto install aSUWAYOMI_EXTENSIONSlist (comma-separated pkgNames) via the GraphQLupdateExtension(input:{id,patch:{install:true}})mutation, idempotently (GET install state first, skip installed). Defaults: Comick (Unoriginal)all.comicklive, MangaDexall.mangadex, Weeb Centralen.weebcentral. - KOMF API path quirk: the REST endpoints are under
/komga(e.g./komga/match/...), not/api/metadata/.... The web UI is a Compose/WASM canvas, so routes can’t be scraped from it — got the paths from the README.
What was striking
- Chapter-1 cover is black, and it’s a source artifact, not config. The ArcaneScans/Comick release ships page
001.webpas a 556-byte blank placeholder (white with two black bars). Komga auto-thumbnails page 1 → black cover. Real content starts at page 2 (full-color Gold Roger spread). No clean declarative fix;bookCoverswon’t help (MangaUpdates has no per-chapter covers). Left as-is — cosmetic, series poster is what matters. - Redeploy was a clean no-op confirmation:
mstack→docker compose up -d→ orchestrator reapplied everything idempotently (library present, all three extensions already installed).
First real backfill — Egghead arc onward
Used the stack for real: bulk-downloaded One Piece ch. 1058–1186 (Egghead arc → latest, 130 chapters) via the Suwayomi GraphQL API. Comick lists ~2500 chapter entries (many scanlators per number), so the trick was deduping to one scanlator per chapter number before enqueuing — otherwise it’s 2-3× duplicates. Downloader sits STOPPED after enqueue and needs an explicit startDownloader; Komga didn’t auto-index on FS events, so a manual library scan was needed. All 131 CBZ indexed cleanly. Recipe captured in Add Manga Stack to Media Stack.
Also confirmed the Suwayomi browse-card blur is inherent: it serves the Comick source cover at 225×322, upscaled on the card. Komga (the actual reader) has the sharp poster, so left it. Suwayomi = downloader/browser, Komga = reader.