This runbook covers the phase-one single-ModelPort deployment. It is designed for a controlled move from the local Compose PostgreSQL database to a managed PostgreSQL service, and for a local PostgreSQL major-version change. It does not perform a migration automatically.
Never point PostgreSQL 18 directly at a PostgreSQL 16 data directory. Major
versions require a reviewed logical dump/restore or a separately designed
pg_upgrade workflow. ModelPort uses logical dump/restore because it also
works with a managed target and keeps the source database available for
rollback.
Before any full Compose update, run:
./scripts/database-preflight.shThe command is read-only and does not print credentials. It fails if the
running PostgreSQL major version or data volume differs from
docker-compose.yml, if SQLx records a failed migration, or if durable state
rows are incomplete. Use ./scripts/compose-up.sh for routine local Compose
updates so this guard runs before an existing database can be replaced.
A preflight failure is a stop condition. docker compose up -d must not be
used to work around it.
For the forty-user target, prefer an operator-managed PostgreSQL service with:
- TLS hostname verification and an explicitly trusted CA;
- point-in-time recovery with RPO no greater than five minutes;
- a tested RTO no greater than thirty minutes;
- restricted ModelPort and migration identities;
- encrypted backups in a different failure domain;
- connection, storage, backup, and replication alerts.
Create a new empty target database. Do not restore over an existing production database, and do not reuse the source database credentials.
-
Record the source ModelPort revision, image digest, PostgreSQL version, migration list, database size, and incident contacts.
-
Create a new schema-v2 backup:
archive="$(./scripts/backup-compose.sh create)" ./scripts/backup-compose.sh verify "$archive" ./scripts/backup-compose.sh drill "$archive" ./scripts/backup-compose.sh upgrade-drill "$archive"
Schema-v2 archives contain the database dump and deployment provenance but no
.envorconfig.toml. Recover configuration from a reviewed Git revision and credentials from the secret manager.upgrade-drillrequires an isolated PostgreSQL 18 target and reports the source and target versions; it never connects ModelPort to the target and never changes the live source database. -
Restore the dump into an isolated target database with the target PostgreSQL
pg_restore,--exit-on-error,--no-owner, and--no-privileges. -
Start the candidate ModelPort revision against only that isolated target. Let embedded SQLx migrations finish before sending requests.
-
Compare source and target counts for
_sqlx_migrations,modelport_state,modelport_gateway_requests,modelport_provider_attempts, budget/evidence tables, and incomplete leases. Compare aggregates, not Prompt or response content. -
Run authenticated readiness, dashboard, backup restore, protocol, Tool Use, and the acceptance suite for each configured local Runtime Adapter. Existing Qwen reference deployments may still use the optional compatibility suite documented in Local Qwen reference adapter.
-
Destroy the rehearsal target only after saving secret-free evidence.
The current phase has one ModelPort instance, so cutover requires a maintenance window:
- Announce the window and stop new client traffic at the reverse proxy.
- Wait for active streams and tool conversations to finish; do not replay a started stream on another Provider.
- Stop only ModelPort and the dashboard. Keep the source PostgreSQL database running and unchanged.
- Create and verify the final schema-v2 backup.
- Restore the final dump to a new empty target database and repeat the row, migration, readiness, and acceptance checks.
- Render short-lived runtime credentials from the secret manager. The
database URL must use
verify-fulland the CA path mounted as/run/modelport/database-ca.pem. - Start the single-instance production Compose profile with digest-pinned images.
- Re-enable traffic gradually and watch readiness, errors, ledger finalizers, latency, Provider health, and PostgreSQL connections.
Keep the source database and previous ModelPort image immutable through the rollback window. If validation fails:
- stop client traffic;
- stop the candidate ModelPort instance;
- restore the previous secret reference and database endpoint;
- start the previous digest-pinned ModelPort image against the untouched source database;
- run readiness and a synthetic request before reopening traffic.
Do not attempt to copy writes from the failed target back into the source. A cutover is complete only after the rollback window closes and backup/restore evidence for the target has passed.
Schema-v1 archives created by older backup-compose.sh versions contain
plaintext runtime configuration and may contain Provider and database
credentials. Verification emits a warning. Keep them at permission 0600,
restrict access, rotate affected credentials, and delete them only under the
organization's approved retention procedure.