DocumentationOperations
Rust · 0.1.0
Upgrade and rollback
Change the application and its persisted state as a planned operation.
Prepare a known candidate
Record the current source commit, image/binary identity and database backup. Build the candidate from an authorized source checkout and review changes to configuration and schema. The application release is 0.1.0; upstream 0.30/0.31 upgrade guides are not this fork's release history. Never force a database's recorded schema number to match the application version.
Test the whole path
Use a disposable copy of database and attachments to rehearse startup and migrations. Then check sign-in, a read/write memo flow, attachment access, integrations and visibility rules. Schedule the production change, stop the old writer cleanly, and monitor the new process. Do not run migration or destructive store tests against production.
Rollback includes data
An older binary may not understand a newer schema. A safe rollback may require restoring the matching pre-upgrade database and files, not merely choosing an older container tag. Restore into isolation and verify first. Keep the upgrade evidence and known-good backup until the new version is accepted.
Rehearse SQLite migration on a copy
First complete a consistent backup. Extract a copy into a new directory named upgrade-check; memos_prod.db below must be that copy, never the live database. Build the candidate binary using Building. inspect is read-only; migrate-copy writes the specified database and requires an explicit test-copy acknowledgement. Do not use these SQLite diagnostics against a PostgreSQL/MySQL DSN.
./build/memos inspect --database ./upgrade-check/memos_prod.db
./build/memos migrate-copy \
--database ./upgrade-check/memos_prod.db \
--confirm-test-copy
./build/memos inspect --database ./upgrade-check/memos_prod.dbStart the candidate against the isolated copy
From the reviewed application checkout, build a distinct candidate image. The upgrade-check directory must contain only your disposable restored SQLite database and local attachment copy. The following starts the full application with no external network and no published port, then probes it from inside the container. Do not point this mount at production. If the container name already exists, inspect that prior test rather than deleting it blindly. A successful health result verifies startup only; run the memo/authentication/file checks described next before a production cutover.
docker build -f scripts/Dockerfile -t memos:candidate .
docker run -d --name memos-upgrade-check --network none \
-e MEMOS_DRIVER=sqlite -e MEMOS_PORT=5230 \
--mount type=bind,src="$PWD/upgrade-check",dst=/var/opt/memos \
memos:candidate
docker logs --tail 100 memos-upgrade-check
docker exec memos-upgrade-check wget -qO- http://127.0.0.1:5230/healthz
docker stop --time 60 memos-upgrade-checkRecord the acceptance result before cutover
Expect inspect to report quickCheck "ok" before and after migration. Compare schemaVersion and preserve the migration report; application version and schemaVersion need not match. If your existing deployment uses an instance URL, pass the same intended --instance-url to migrate-copy and review access policy afterward. A migration failure stops the rehearsal: retain logs and the untouched backup rather than editing the schema number. Once the candidate passes isolated functional checks, stop the old writer, take the final consistent backup, start the candidate and repeat health, sign-in, memo and file checks.
Make rollback a matched pair
Write down the rollback pair before changing production: old image/binary plus its pre-upgrade database, attachment snapshot and configuration. If rollback is needed, first stop the candidate so it cannot keep writing while old data is restored. Restore into a new destination, validate the old build against that data, then switch traffic. Notes written after the backup are not in that restore; decide how to preserve or reconcile them before discarding the candidate data.