NodePad upgrades are designed to fail fast and fail safe: schema migrations run before any application pod rolls, and an upgrade that breaks migrations leaves your existing pods serving the old version.
Upgrade checklist
Kubernetes (Helm)
Upgrade
helm upgrade nodepad oci://ghcr.io/palazski/charts/nodepad \
--version 0.3.0 \
-f values.yaml
Schema migrations run automatically as a pre-upgrade Helm hook before any api/worker/beat pods roll. The upgrade fails fast if migrations fail; your existing pods keep serving on the old version.
Rollback
# List release history
helm history nodepad
# Roll back to the previous revision
helm rollback nodepad <REVISION>
Helm rollback does NOT undo schema migrations. If the forward migration was destructive (dropped columns, changed types), rolling the code back leaves the old code facing a newer schema.Mitigations:
- Keep migrations additive and backwards-compatible within a minor line.
- Before any destructive migration, back up the database (see below).
- Any non-reversible migration is flagged in the changelog for that release.
Database backup before upgrade
pg_dump "$NODEPAD_DATABASE_URL" > nodepad-pre-v0.3.0.sql
kubectl exec -it <release>-postgresql-0 -- \
pg_dump -U nodepad nodepad > nodepad-pre-v0.3.0.sql
Single-VM (docker compose)
Upgrade
# 1. Pull new images (or load from an offline bundle)
docker compose pull
# 2. Restart with migrations enabled.
# NODEPAD_RUN_MIGRATIONS_ON_START=1 is the compose default —
# migrations run automatically on api container start.
docker compose up -d
Rollback
The compose file reads VERSION from .env. Bump it and re-up:
sed -i 's|^VERSION=0.3.0|VERSION=0.2.4|' .env
docker compose pull
docker compose up -d
# If the upgrade included a destructive migration, restore from backup:
# docker compose exec db psql -U nodepad -d nodepad < nodepad-pre-v0.3.0.sql
Migration-incompatible rollback
If you must roll a release back across an irreversible migration:
Quiesce writes
Scale api/worker/beat to 0 replicas.
Restore the database
Use the pre-upgrade backup.
Redeploy the old version
Pin to the previous semver tag.
Scale back up
Return replicas to their original values.
This loses any data written after the upgrade. Plan migrations to avoid this when possible.