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
| Area | Provided by Kavita_Common | Where it surfaces |
|---|---|---|
| Authentication | No generated secrets — the administrator account is created through Kavita's first-run setup wizard at / | Kavita web UI on first access |
| JWT signing key | Not injectable — Kavita auto-generates the appsettings.json TokenKey on first boot and persists it on the /kavita/config volume | Managed internally by Kavita; nothing to inject |
| Container image | Thin-wraps the official jvmilazz0/kavita image so the foundation can mirror it into Artifact Registry | container_image output of the platform deployment |
| Database engine | None — Kavita uses an internal SQLite database (kavita.db) under /kavita/config (database_type = "NONE") | §Database in the platform guides |
| Database bootstrap | None — there is no db-init job; Kavita manages its own storage | n/a |
| Object storage | Declares the Cloud Storage storage bucket that backs /kavita/config on Cloud Run | storage_buckets output |
| Core settings | Sets DOTNET_gcServer = "0" and the container port 5000 | Application behaviour in the platform guides |
| Health checks | Supplies 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.json→TokenKey) is auto-generated by Kavita on first boot and persisted on the/kavita/configvolume. 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 asmodule_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-initjob — 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 = falseis 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 genericAPP_VERSIONthat the foundation injects (and would force tolatest). Whenapplication_version = "latest"the Common layer pins the build to0.8.7; otherwise it passes the requested version straight through. This avoids resolving a non-existentkavita: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'scontainer_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
storageCloud Storage bucket at/kavita/configvia GCS FUSE (enable_gcs_storage_volume = true). - GKE with
stateful_pvc_enabled = true(the default) mounts a block PVC at/kavita/configand setsenable_gcs_storage_volume = falseto 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 probe —
initial_delay = 15s,timeout = 5s,period = 10s,failure_threshold = 10. - Liveness probe —
initial_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, withpublic_access_prevention = "enforced".- The bucket
locationis 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/configvia 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.