Skip to main content
Use a snapshot to rehearse a schema migration against a realistic PostgreSQL data directory, inspect the result, and return to the exact pre-migration disk state. The disposable rehearsal does not require a down migration.
Keep PGDATA in the sandbox root filesystem for this example. This keeps the database self-contained in the captured root disk. Do not rely on external named-directory or bind-mounted storage being copied into the snapshot.

Rehearse a migration

1

Create an initialized baseline

Set a temporary password in the host shell:
Start the baseline database. The shell keeps the VM available after PostgreSQL stops, until the explicit msb stop below:
Wait for initialization, then stop the database cleanly:
Shut PostgreSQL down with its own control command before stopping the VM and taking the snapshot. VM shutdown alone does not guarantee a clean database shutdown:
2

Snapshot the baseline

Verify the captured snapshot:
3

Apply the migration

Restore into an unused sandbox name, then start PostgreSQL explicitly. Dedicated restore boots an idle detached sandbox instead of running the image entrypoint. The database, role password, and initialization settings already live in the captured data directory; the POSTGRES_* initialization variables do not need to be replayed.pg_ctl starts PostgreSQL in its own process group with output redirected to the log, so it survives the startup exec completing. The separate status check below reconnects after that exec has exited.
Wait for the restored database to become ready:
Apply a sample destructive change and verify it:
Replace those statements with your real migration command and validation suite.
4

Roll back by replacing the sandbox

Stop the mutated database and boot another clean copy of the baseline under the same name:
After removing the stopped sandbox, restore a fresh copy under the same name and start PostgreSQL:
Wait for the clean database to become ready:
Confirm the sample table is absent:
The result should be rolled-back.
5

Clean up

Stop the restored database cleanly, then remove the stopped sandboxes:
Remove the snapshot:
Clear the password from the host shell: