Skip to main content

Kavita Common — Shared Application Configuration

Kavita_Common is the shared application layer for Kavita. It is not deployed on its own; instead it supplies the Kavita-specific configuration that both Kavita_GKE and Kavita_CloudRun build on, so the two platform variants behave identically where it matters. End users never configure this layer directly — it has no deployment UI inputs of its own — but understanding what it provides explains the defaults you see in the platform docs.

For the infrastructure that actually provisions and runs Kavita, see the platform guides (Kavita_GKE, Kavita_CloudRun) and the foundation guides (App_GKE, App_CloudRun, App_Common).


1. What this layer provides

AreaProvided by Kavita_CommonWhere it surfaces
AuthenticationNo generated secrets — the administrator account is created through Kavita's first-run setup wizard at /Kavita web UI on first access
JWT signing keyNot injectable — Kavita auto-generates the appsettings.json TokenKey on first boot and persists it on the /kavita/config volumeManaged internally by Kavita; nothing to inject
Container imageThin-wraps the official jvmilazz0/kavita image so the foundation can mirror it into Artifact Registrycontainer_image output of the platform deployment
Database engineNone — Kavita uses an internal SQLite database (kavita.db) under /kavita/config (database_type = "NONE")§Database in the platform guides
Database bootstrapNone — there is no db-init job; Kavita manages its own storagen/a
Object storageDeclares the Cloud Storage storage bucket that backs /kavita/config on Cloud Runstorage_buckets output
Core settingsSets DOTNET_gcServer = "0" and the container port 5000Application behaviour in the platform guides
Health checksSupplies the default startup/liveness probes targeting /api/health§Observability in the platform guides

2. Secrets in Secret Manager

Kavita has no injectable service secret. Unlike database-backed applications, it does not require an operator-supplied encryption key, admin token, or JWT signing secret to be created ahead of time:

  • The administrator account is created interactively through the first-run setup wizard the first time you open the web UI at /.
  • The JWT signing key (appsettings.jsonTokenKey) is auto-generated by Kavita on first boot and persisted on the /kavita/config volume. It is never minted by Terraform and is not stored in Secret Manager.

As a result both of the Common layer's secret outputs are empty:

  • secret_ids{} (forwarded to the foundation as module_secret_env_vars)
  • secret_values{} (forwarded as the explicit secret-value map)

They are kept as outputs purely so the CloudRun/GKE wrappers can wire them uniformly alongside apps that do have generated secrets. There is nothing to retrieve from Secret Manager for a stock Kavita deployment; any secrets you add manually via the platform's secret_environment_variables input are the only entries you will find:

# List secrets for this deployment (names include the resource prefix):
gcloud secrets list --project "$PROJECT" --filter="name~kavita"

See App_Common for the shared secret and Workload Identity model.


3. Database engine and bootstrap

Kavita does not use an external database. All of its state — the library index, user accounts, reading progress, bookmarks, collections, and settings — lives in an internal SQLite database (kavita.db) written under /kavita/config, alongside cover images, generated thumbnails, backups, and logs. Consequently:

  • database_type = "NONE" — no Cloud SQL instance, database, or user is created for Kavita.
  • There is no db-init job — Kavita creates and migrates its own SQLite schema on first boot; nothing has to be bootstrapped ahead of time.
  • No PostgreSQL extensions, no pgvector, and no Redis are involved (enable_redis = false is forced by both platform wrappers).

Because the database is a file on the persistent /kavita/config volume, durability is a function of the storage backend, not a managed database service (see §5 and §7). If you need custom data-loading or migration tasks, you can supply your own initialization_jobs; none is provided by default.


4. Container image and entrypoint

Kavita uses a thin-wrapper Dockerfile — it does not add a custom entrypoint script and runs the upstream image's own entrypoint unchanged:

ARG KAVITA_VERSION=0.8.7
FROM jvmilazz0/kavita:${KAVITA_VERSION}
  • image_source = "custom" — this is set purely so the foundation builds/mirrors the image into Artifact Registry; there is no application code layered on top.
  • App-specific build ARG — the Dockerfile reads KAVITA_VERSION, not the generic APP_VERSION that the foundation injects (and would force to latest). When application_version = "latest" the Common layer pins the build to 0.8.7; otherwise it passes the requested version straight through. This avoids resolving a non-existent kavita:latest-derived tag at build time.
  • No entrypoint translation — because Kavita needs no database wiring or URL rewriting at boot, the upstream image's default startup is used as-is.

5. Core application settings

Kavita_Common establishes the minimal environment Kavita needs to come up on first boot and write its state to the persistent volume:

  • DOTNET_gcServer = "0" — selects the .NET workstation garbage collector rather than the server GC, which keeps Kavita's memory footprint low and steady on a small single-instance container.
  • Container port 5000 — Kavita serves HTTP on port 5000 by default, matching the module's container_port.
  • Fixed state directory /kavita/config — Kavita's configuration, SQLite database, cover images, bookmarks, backups, and logs all live under this single directory, which is baked into the image. Everything Kavita persists lives here.
  • No telemetry, queue, or execution-mode settings — there is nothing further to configure at boot; the rest of setup (admin account, libraries) happens through the web UI's first-run wizard.

Platform-specific mounting of /kavita/config:

  • Cloud Run mounts the storage Cloud Storage bucket at /kavita/config via GCS FUSE (enable_gcs_storage_volume = true).
  • GKE with stateful_pvc_enabled = true (the default) mounts a block PVC at /kavita/config and sets enable_gcs_storage_volume = false to avoid a double-mount at the same path (gcsfuse would also corrupt Kavita's SQLite database and index files).

Note that this module persists only Kavita's state directory. The actual library content (comics, manga, ebooks) is expected to be provided through mounted volumes — additional gcs_volumes or an NFS mount — that you then register as libraries inside the Kavita UI.


6. Health probe behaviour

Both the startup and liveness probes issue an HTTP GET /api/health, Kavita's public, unauthenticated endpoint that returns 200 once the server is serving — so the probes pass independent of any admin login or library scan.

  • Startup probeinitial_delay = 15s, timeout = 5s, period = 10s, failure_threshold = 10.
  • Liveness probeinitial_delay = 30s, timeout = 5s, period = 30s, failure_threshold = 3.

7. Object storage

A single Cloud Storage bucket is declared here and provisioned by the foundation, which also grants the workload service account access:

  • name_suffix = "storage", storage class STANDARD, force_destroy = true, versioning disabled, with public_access_prevention = "enforced".
  • The bucket location is left empty so the foundation resolves it via the auto-discovered deployment region (avoiding a force-replace of the immutable-location bucket on a cross-region re-apply).
  • On Cloud Run it backs /kavita/config via GCS FUSE, so it holds Kavita's SQLite database, cover images, bookmarks, backups, and logs.

List it with:

gcloud storage buckets list --project "$PROJECT"

Note on storage type. Kavita's /kavita/config is SQLite-heavy and benefits from block storage for low-latency random I/O. On GKE the block PVC (stateful_pvc_enabled = true) is the best fit. Cloud Run's GCS FUSE mount works but has higher latency and is better suited to light libraries; large libraries and frequent metadata scans are far happier on the GKE block PVC.


For the Kavita-specific, user-facing configuration (variables by group, outputs, and how to explore each service from the Console and CLI), see the platform guides: Kavita_GKE and Kavita_CloudRun.