Skip to main content

Overview

See Config Store for what this is and why it’s separate from backend/redisUrl. This page covers deploying it: schema migrations, Docker/Compose, and the Helm chart’s SQLite-vs-Postgres handling. By default, no config store is configured — admin-API changes don’t survive a restart, same as before this feature existed. Set server.configStoreUrl (or the chart’s configStore.dialect) to change that.

Schema migrations

The config store’s schema is managed with Alembic, applied via a dedicated CLI command — not automatically at process startup, so an operator (or the Helm chart, see below) controls exactly when a migration runs relative to a rollout.
PROXY_HOPPER_CONFIG_STORE_URL works in place of --database-url too. migrate requires the proxy-hopper-sql package, already bundled into the standard Proxy Hopper Docker images — no separate image variant to pick.
Run migrate before starting Proxy Hopper against a config store URL for the first time. Both dialects are idempotent to re-run — a migrate call against an already-current schema is a no-op, not an error.

Docker / Docker Compose

For SQLite, mount a volume for the database file and point both the one-shot migrate run and the main process at the same path:

Kubernetes / Helm

The chart selects the migration mechanism from configStore.dialect, not from sniffing the URL — Helm can’t read the contents of configStore.existingSecret at template-render time (unlike Proxy Hopper itself, which always detects the dialect from the URL’s SQLAlchemy scheme at runtime).

Postgres — any replica count

The chart runs migrations via a Job annotated helm.sh/hook: pre-install,pre-upgrade — it completes before the proxy/admin Deployments roll out on every install and upgrade. Since Postgres is a real multi-writer server, this works with any replicaCount, autoscaling.enabled, and alongside a separately-enabled admin.enabled Deployment — all can point at the same database.

SQLite — single pod only

The chart provisions a PVC and mounts it on the main deployment, with an initContainer that runs proxy-hopper migrate against that pod’s own local file before the main container starts — the same structural pattern as the chart’s existing wait-for-redis initContainer, but for schema migration instead of a readiness check.
SQLite is single-writer. The chart enforces this at render time: helm template/helm install fails outright if configStore.dialect: sqlite is combined with replicaCount greater than 1 or autoscaling.enabled: true, rather than silently deploying pods that get stuck in FailedAttachVolume trying to mount the same ReadWriteOnce PVC. Use configStore.dialect: postgres if you need more than one replica.For the same reason, configStore.dialect: sqlite is not wired into a separately-enabled admin.enabled Deployment — it would be a second Deployment trying to reach the same single-writer file, which the chart doesn’t attempt to make safe. An admin Deployment falls back to no config store (same as configStore.dialect unset) when the main deployment uses SQLite. Use Postgres if the admin server needs to see the same durable config as the proxy runners.

Verifying

See also

Config Store

The concept guide — what’s durable vs. ephemeral, and why they’re separate.

Config Reference

configStoreUrl / PROXY_HOPPER_CONFIG_STORE_URL alongside the rest of server:.

High Availability

Operational-state HA via the Redis backend — a separate, orthogonal choice from config durability.

ConfigStore internals

The ConfigStore interface and how to add a new dialect, for contributors.