Production checklist
Upgrade with a distribution manifest
v0.5.0 resets the Prisma migration history to one final-schema baseline and is
for fresh installations only. Existing v0.4.1 and earlier databases do not have
a supported upgrade path to v0.5.0. Keep those installations on their current
release; the v0.5.0 upgrade.sh fails before changing Compose or PostgreSQL.
Releases whose distribution-manifest.json lists the upgradeScript artifact
ship upgrade.sh as a versioned release asset alongside the manifest.
distribution-manifest.json is also included in the tagged source (see
Production Compose). Older releases
without that manifest entry do not ship upgrade.sh as a release asset; obtain
the script from the matching tagged source tree instead. The distribution
manifest checksums upgrade.sh and the other listed release assets; the
manifest plus its listed assets are verified before publication.
The procedure below is the canonical current upgrade path. Migrations are
forward-only; there is no automatic rollback.
Prerequisites
Before starting, gather the exact target release assets and plan a maintenance
window:
- Download
distribution-manifest.json and upgrade.sh from the GitHub release
assets for the matching tag.
- Install Docker Compose v2 and Node.js on the operator host.
- Read the changelog for the target release and note schema or environment
changes. Review
.env.example against the current .env and update
deliberately.
- Schedule a maintenance window or stop writes before touching the database.
- Never enable demo OTP or demo seeding on a production deployment.
Backup as rollback
A tested application PostgreSQL backup, matching application secrets, and
applicable Temporal persistence are the rollback mechanism. Create the backup
before starting the upgrade; see
Backup and restore. Migrations are forward-only;
an image rollback does not reverse Prisma migrations.
Verify release assets
When the manifest contains upgradeScript, the script verifies the manifest,
target version, and listed images before it touches services or the database.
Run the canonical invocation with the exact target version:
Without --compose-file, the script uses compose.yaml next to it. To layer
overlays, pass the base file first and repeat --compose-file for
compose.worker.yaml and compose.temporal.yaml in order:
A manifest, version, or image mismatch returns nonzero and stops the upgrade
before any service or database change.
Stop services
After verification succeeds, the script pulls the selected release images and
stops app and worker when the rendered Compose configuration includes them.
It detects the service set from compose config --services rather than
assuming a worker service always exists.
Run migrations
The script runs the one-shot db-migrations service with
prisma migrate deploy for the full Prisma tree and then all blocking data
migrations before the web app. The migration container’s exit code is
propagated: a failed verification or migration returns nonzero and prevents
app/worker restart.
The migration ledger distinguishes completed data work from final completion.
If optional finalization fails, the command exits nonzero and records the
finalization error while leaving the migration unfinished. Rerun
npm run db:migrate; it retries finalization without repeating completed data
work. Existing rows already marked finishedAt remain final after upgrading.
After an upgrade that adds competitor organic snapshots, optionally compact the
latest completed SERP for each keyword into the new query-friendly column:
Run the command with DATABASE_URL available. It is batched and idempotent,
and leaves checks without a usable historical organic payload unchanged. The
app continues to read those legacy payloads directly, so the backfill does not
need to block the web deployment.
Restart
After a successful migration, the script starts the selected app and
worker services from the matched release images. It does not perform the
operator’s post-start readiness checks; those are the next step.
Validate readiness
After the script returns success, confirm the deployment is healthy:
-
Call authenticated
GET /api/v1/health with an API credential or the
deployment’s INTERNAL_PROBE_TOKEN Bearer header. Confirm
services.migrations is ready; the endpoint returns 503 when a bundled
Prisma migration has not been applied, an active data migration is
incomplete, has a checksum mismatch, or cannot be read, or the public ID
database contract is not ready.
-
Sign in and read one project to confirm the app serves authenticated
requests.
-
Check Prisma status in Docker Compose:
-
Confirm the web and worker report the same release. For split deployments,
deploy the web app so migrations apply, then immediately deploy the worker
from the same release tag. Version skew commonly appears as “The column …
does not exist” errors in worker logs or as failing scheduled checks while
the web app works.
-
When scheduled work is enabled, confirm the Temporal worker reports ready
and its maintenance schedules are created or already exist.
/api/v1/readiness is the public traffic-admission (readiness) probe; it does
not replace the authenticated health checks above. Use /api/v1/liveness for
restart probes and authenticated GET /api/v1/health for the deeper
service/migration contract. See
Backup and restore for its role in restore
validation.
Failure paths
A failed verification or migration returns nonzero and prevents app/worker
restart. No success is reported. The script does not perform automatic rollback.
Inspect the migration output before retrying or restoring. If a migration left
the database in an intermediate state, a database restore may be required; see
Restore from backup below.
Restore from backup
If the upgrade cannot complete, restore the pre-upgrade database backup with
the matching previous release. Restoring must use the same bisibility release
that created the dump; an image rollback alone does not reverse Prisma
migrations. See Backup and restore for the
full restore procedure, including stopping writers, running migrations after
restore, and readiness validation.
Legacy upgrades
Older one-time source upgrades have their own pages and are kept for
reference.
Upgrade from v0.1.0 to v0.2.0
This one-time source upgrade has its own page:
Upgrade from v0.1.0 to v0.2.0.