Skip to content

komf

Metadata engine for Komga — running in the komga stack on the arrstack VM. Fetches series/book metadata and covers from online providers and writes them into Komga over its REST API.

LAN URL: http://192.168.1.252:8085. No public route — LAN-only admin UI.

Why it's needed

Neither Komga nor Kapowarr populates rich metadata on its own:

  • Komga has no built-in online scraper. It only reads metadata embedded in the file (ComicInfo.xml) or infers it from the filename (gotson/komga#1577). Well-tagged releases look great; untagged ones show a bare filename-derived title and no creators, summary or cover art.
  • Kapowarr doesn't write ComicInfo.xml. It matches ComicVine for its own naming/organising only (Casvt/Kapowarr#50) — that matching never reaches Komga.

komf closes that gap. The pipeline is Kapowarr gets & organises → Komga displays → komf makes the metadata accurate.

Service details

Property Value
Host arrstack VM (192.168.1.252) — see arrstack service page
Image sndxr/komf:latest (upstream repo)
Config storage named volume komf_config (/configapplication.yml + state)
Host port 8085
Komga connection KOMF_KOMGA_BASE_URI=http://komga:25600 (service name on the komga network)
Auth dedicated Komga user komf@rampancy.cloud; password in KOMF_KOMGA_PASSWORD
Metadata source ComicVine (Western) + MangaUpdates / AniList / MangaDex / others
Egress Direct — not tunnelled (see below)
Compose stacks/komga/docker-compose.yml
Backup komf_config sits under /var/lib/docker/volumes/ — part of the VM's vzdump snapshot

Not behind the VPN — deliberately

Unlike Kapowarr, komf is not routed through gluetun. It only talks to metadata provider APIs (ComicVine, MangaUpdates, AniList…) and to Komga on the local Docker network — no DDL, no torrents, nothing to hide. It also needs to resolve komga on the stack network, which netns-sharing a VPN container would complicate for no benefit.

Sources

Covers both halves of a mixed library:

  • ComicVine — Western comics / graphic novels (the canonical DB for them).
  • MangaUpdates, AniList, MangaDex, MAL, Bangumi, Yen Press, Kodansha, Viz, BookWalker and others — manga.

The ComicVine API key is shared with Kapowarr (entered separately in each app's own config). They share ComicVine's ~200 req/hour limit, so stagger large library scans.

Update modes — API vs COMIC_INFO

Mode What it does Trade-off
API (in use) Writes metadata + covers straight into Komga's database over the REST API Non-destructive — never touches the files. Metadata lives only in Komga's DB, so a DB rebuild means re-running komf. No library mount needed.
COMIC_INFO Writes ComicInfo.xml into the CBZ files themselves Metadata becomes portable — it travels with the files and survives a Komga rebuild. Modifies the archives, and needs the comics library mounted into the komf container.

We run API mode. COMIC_INFO is available if portable metadata is ever wanted — the library is mounted :rw since 2026-07-09, so the only extra step would be adding the /comics mount to the komf service.

Komga account

komf authenticates as a dedicated komf@rampancy.cloud Komga user (created in Server Settings → Users) rather than reusing the admin login — least privilege for a service account. It needs permission to edit metadata; if a standard user hits permission errors, grant that account elevated rights (it's a trusted internal service).

Only the password lives in the stack .env (KOMF_KOMGA_PASSWORD); the username is set in the compose.

Bootstrap — /config/application.yml must be seeded by hand

komf does not create a default config

On a fresh komf_config volume komf crash-loops immediately with java.nio.file.NoSuchFileException: /config/application.yml. It requires the file to exist and will not generate one. The compose env vars alone are not enough.

Because the config lives in a named volume, it is not captured in Git — so a rebuild must re-seed it. Current file was seeded 2026-07-18 to /var/lib/docker/volumes/komf_config/_data/application.yml on the arrstack VM.

Auto-matching is DISABLED — eventListener.enabled: false

komf's event listener subscribes to Komga's SSE stream and automatically matches every newly added series with no prompting. It was initially enabled, and on 2026-07-18 it silently mis-matched two newly added series:

  • Astro City (Kurt Busiek superhero comic) → matched to "Astro Baby" from MangaUpdates
  • Lobo (1990) → matched via ComicVine, also rewriting book-level metadata

Both were reset. The listener is now off, and metadata matching for this library is manual only — triggered deliberately via the API (POST /komga/identify, /komga/match/...) or the browser extension. Verify it stays off with: docker logs komf | grep -c "connected to Komga event source" — it should be 0.

Do not re-enable without first fixing provider priority and ComicVine's bookMetadata fields (see roadmap §6H).

Key settings in use:

Setting Value Why
libraryType COMIC Library is Western comic/GN heavy
updateModes [ API ] Writes into Komga's DB; doesn't touch files
seriesCovers true, overrideExistingCovers: false Fetch covers, but don't replace existing ones
database.file /config/database.sqlite Keep state inside the volume
Providers mangaUpdates (10) → comicVine (20) See below

Provider ordering is deliberate. mangaUpdates is set to higher priority even though the library is comic-heavy: its mediaType: MANGA filter means it only positively matches manga, so Western comics fall through to comicVine. That routes a mixed library correctly with one provider list.

An enabled provider without its API key blocks startup

komf validates provider config at boot and throws IllegalArgumentException: Api key is not configured for ComicVine provider — it will not start in a degraded mode. So while comicVine is enabled, KOMF_METADATA_PROVIDERS_COMIC_VINE_API_KEY must be set in the stack env. If you ever need komf up without a ComicVine key, disable the provider in application.yml rather than leaving the key blank.

Harmless startup race

On a stack redeploy komf usually logs a few Event source error / ConnectException: Failed to connect to komga/…:25600 warnings before succeeding with connected to Komga event source. depends_on waits for Komga's container to start, not to be ready — komf retries and connects within ~15s. Not a fault.