Skip to content

Configuration

Updated View as Markdown

kmrs --help lists the CLI flags (--config-dir, --port). The configuration file is always <config-dir>/config.toml; on first start it is generated from the built-in defaults, carrying over values from the Java komga’s application.yml/application.yaml found in the same directory.

Precedence (lowest to highest): defaults < TOML file < env vars (Spring relaxed binding, e.g. KOMGA_DATABASE_FILE) < CLI flags.

Full key reference

Every key below is commented out at its default value; uncomment to change it. Also available as examples/config.toml in the repository.

[server]
# port = 25600 # env: SERVER_PORT; CLI: --port
# session-timeout = "7d" # env: SERVER_SERVLET_SESSION_TIMEOUT; "500ms"/"10s"/"30m"/"1h"/"7d", bare integer = seconds
# context-path = "/" # env: SERVER_SERVLET_CONTEXT_PATH; URL prefix, empty = root
# sort-locale = "zh-CN" # env: KOMGA_SORT_LOCALE; BCP47 language tag for ICU sorting, empty/absent = root collation

[cors]
# allowed-origins = [] # env: KOMGA_CORS_ALLOWEDORIGINS (comma-separated)

[database]
# file = "<config-dir>/database.sqlite" # env: KOMGA_DATABASE_FILE
# pool-size = 4 # read pool size; default min(CPU cores, max-pool-size). env: KOMGA_DATABASE_POOLSIZE
# max-pool-size = 4 # env: KOMGA_DATABASE_MAXPOOLSIZE
# journal-mode = "WAL" # WAL/DELETE/TRUNCATE/PERSIST/MEMORY/OFF; env: KOMGA_DATABASE_JOURNALMODE
# busy-timeout = "30s" # default 30s when unset; env: KOMGA_DATABASE_BUSYTIMEOUT
# Task execution (library scan / analysis / hashing / conversion / maintenance)
# uses a dedicated read/write pool over the same database file, so background
# tasks never contend with HTTP/API connections for pool slots. The task write
# pool is a second writer on the file; keep a busy timeout (default 30s) so
# concurrent writes wait instead of failing.
# [database.pragmas] # extra SQLite pragmas, TOML only
# synchronous = "NORMAL"

[tasks-db]
# file = "<config-dir>/tasks.sqlite" # env: KOMGA_TASKSDB_FILE; same keys as [database], env prefix KOMGA_TASKSDB

[kmrs-db]
# file = "<config-dir>/kmrs.sqlite" # kmrs-private state (per-book series metadata contributions, komf integration); env: KOMGA_KMRSDB_FILE; same keys as [database], env prefix KOMGA_KMRSDB

[search]
# data-directory = "<config-dir>/lucene" # tantivy index; env: KOMGA_LUCENE_DATA_DIRECTORY

[fonts]
# data-directory = "<config-dir>/fonts" # env: KOMGA_FONTS_DATA_DIRECTORY

[books]
# page-hashing = 3 # env: KOMGA_PAGEHASHING
# epub-divina-letter-count-threshold = 15 # env: KOMGA_EPUBDIVINALETTERCOUNTTHRESHOLD

[libraries]
# only consulted when database migrations run (fresh or upgraded data directory)
# file-hashing = true # env: KOMGA_FILEHASHING
# scan-on-startup = false # env: KOMGA_LIBRARIESSCANSTARTUP
# delete-empty-collections = true # env: KOMGA_DELETEEMPTYCOLLECTIONS
# delete-empty-read-lists = true # env: KOMGA_DELETEEMPTYREADLISTS

[kobo]
# sync-item-limit = 100 # env: KOMGA_KOBO_SYNCITEMLIMIT
# kepubify-path = "/usr/local/bin/kepubify" # env: KOMGA_KOBO_KEPUBIFYPATH


[webhooks]
# generic JSON POST webhooks on library events (kmrs enhancement, no Java equivalent)
# Per-endpoint configuration (each endpoint has its own URL, events, secret):
# [[webhooks.endpoints]]
# url = "https://example.com/webhook1"
# events = ["BookAdded", "SeriesAdded"]  # empty = all events
# secret = "hmac-secret"  # empty = unsigned
#
# [[webhooks.endpoints]]
# url = "https://example.com/webhook2"
# events = ["BookAdded"]
# secret = ""
#
# timeout = "10s" # per-request POST timeout. env: KOMGA_WEBHOOKS_TIMEOUT
#
# Precedence: [[webhooks.endpoints]] in TOML file takes priority.
# If no endpoints are defined in the file, env vars are used as fallback:
# KOMGA_WEBHOOKS_URLS (comma-separated), KOMGA_WEBHOOKS_EVENTS,
# KOMGA_WEBHOOKS_SECRET, KOMGA_WEBHOOKS_TIMEOUT

[oauth2]
# account-creation = false # env: KOMGA_OAUTH2ACCOUNTCREATION
# oidc-email-verification = true # env: KOMGA_OIDCMAILVERIFICATION
# One table per provider; setting `issuer-uri` switches it to OIDC discovery mode.
# env vars SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_<ID>_*/PROVIDER_<ID>_* override single fields.
#
# [oauth2.registrations.github]
# client-id = "..."
# client-secret = "..."
# client-name = "GitHub" # defaults to the registration id
# authorization-grant-type = "authorization_code"
# redirect-uri = "{baseUrl}/login/oauth2/code/{registrationId}"
# scopes = ["read:user", "user:email"]
# issuer-uri = "https://accounts.google.com"
# authorization-uri = "..."
# token-uri = "..."
# user-info-uri = "..."
# user-name-attribute = "..."

[webui]
# serve a built web UI (e.g. kmweb's dist/) at /; unmatched paths fall back to its index.html
# dir = "/path/to/kmweb/dist" # env: KOMGA_WEBUI_DIR
# auto-update = false # track the latest kmweb release into <config-dir>/webui; env: KOMGA_WEBUI_AUTOUPDATE
# update-interval = "1d" # env: KOMGA_WEBUI_UPDATEINTERVAL

[komf]
# komf metadata fetcher integration (kmrs enhancement, no Java equivalent);
# pre-fills the setup form in the admin UI — nothing is provisioned until an admin confirms
# komf's API has no authentication — only point this at a trusted network
# url = "http://komf:8085" # env: KOMGA_KOMF_URL
# base-url = "http://kmrs:25600" # env: KOMGA_KOMF_BASEURL

[history]
# retention for the history event table (kmrs enhancement; the Java version keeps events forever)
# retention-days = 180 # 0 = keep forever; env: KOMGA_HISTORY_RETENTIONDAYS

[thumbnails]
# where book/series thumbnail bytes live (kmrs enhancement; Java always uses DB blobs)
# storage = "db" # db = blobs in the database, file = files under <config-dir>/thumbnails; env: KOMGA_THUMBNAILS_STORAGE
# answer If-None-Match from the thumbnail row instead of hashing the body (kmrs enhancement; Java always hashes)
# deep-etag = true # false = hash the body like the Java version; env: KOMGA_THUMBNAILS_DEEPETAG
Navigation

Type to search…

↑↓ navigate↵ selectEsc close