Deployment

Deploy and maintain Kival beyond local exploration.

Kival is self-hosted. The current production model is straightforward: one active kivald process, PostgreSQL, and a persistent local data directory for attachment blobs.

This page describes that supported boundary. It does not imply a multi-server Kival topology that the current local attachment store cannot safely provide.

Requirements

A deployment needs:

  • a supported kivald binary;

  • PostgreSQL 18;

  • a persistent data directory writable by the Kival service user;

  • a stable public HTTPS origin;

  • a reverse proxy or equivalent TLS terminator for internet-facing use.

The web application is embedded in kivald; there is no separate frontend service to deploy.

PostgreSQL and persistent data

Kival stores application state in PostgreSQL. Configure a dedicated database role and connection string, and size the database pool for the deployment rather than relying on accidental defaults.

Attachment bytes live under the configured Kival data directory, currently in <datadir>/blobs. Backups therefore need both PostgreSQL and the persistent data directory.

Do not run multiple active kivald processes against one database while each has an independent local blob store. PostgreSQL can be remote; the attachment boundary is still local to the server process.

Configure the public origin

Passkeys depend on WebAuthn origin and relying-party configuration. Set Kival's canonical public URL to the HTTPS origin users actually visit, and configure allowed origins accordingly.

Changing hostnames later is a security-sensitive migration, not just a cosmetic URL change.

Run behind TLS

kivald serves HTTP and does not terminate public TLS itself. Put it behind a reverse proxy, load balancer, or ingress that terminates HTTPS and forwards requests to the Kival listener.

The same server exposes the embedded application, /api/v1, and the authenticated realtime endpoint, so the proxy must support normal HTTP and WebSocket upgrades.

Keep the Kival listener private to the host or trusted network when the reverse proxy is the public boundary.

Service supervision and health

Run kivald serve under a supervisor such as systemd, a container runtime, or another service manager that can restart the process and send normal termination signals during deployment.

Kival exposes health/readiness endpoints for infrastructure checks. Use readiness for traffic admission and deployment coordination rather than treating process existence alone as proof that the database-backed service is usable.

Metrics and logs

Prometheus metrics are optional and served on a separate listener when enabled. Keep that listener private unless you have a deliberate reason to expose it.

Application logs go to the normal process output and should be collected by the surrounding runtime. Configure log verbosity at the deployment boundary rather than depending on interactive terminal behavior.

Backups and upgrades

A usable backup includes:

  1. PostgreSQL;

  2. the Kival data directory containing attachment blobs.

Coordinate them closely enough that database attachment metadata and blob contents represent the same recovery point, and test restoration rather than assuming a successful copy is sufficient.

For upgrades, back up first, stop or drain the active Kival process, install the new binary, then start it and verify readiness. Follow release notes for version-specific migration requirements.

Bootstrap the first administrator

A new deployment needs an initial global administrator. Bootstrap is an operator action performed through kivald admin, which connects directly to PostgreSQL rather than relying on an already functioning browser login.

After bootstrap, routine administration should happen through Kival's normal administrative surfaces. See Administration.