Add backup and restore commands with Postgres 18 upgrade - #174
Merged
Conversation
One bundle carrying a custom-format pg_dump, the uploads, and a manifest; taken over DIRECT_DATABASE_URL when set, the same selection migrations make. On S3 the bundle records the bucket and pulls nothing unless --uploads include asks for every object. restore goes only into a new, empty database, applies any migrations the dump predates, counts the restored posts, and puts the uploads back — onto local disk or up to the configured bucket. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LYancK1YxtRYHHEmtoqRPA
postgres:18-alpine everywhere postgres:16-alpine was pinned, with the pgdata mounts moved to /var/lib/postgresql because the 18 image keeps its cluster below that path rather than at /data. The runtime image adds postgresql18-client so the backup and restore verbs work where the CLI works. BREAKING CHANGE: an existing board does not cross the Postgres major by redeploying — the old data directory would be ignored, not upgraded. docs/upgrading.md#when-a-release-moves-postgres is the backup-and-restore path across. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LYancK1YxtRYHHEmtoqRPA
A backup job seeds the demo board plus an upload, takes a bundle, restores it into a fresh database and a fresh uploads directory, proves the restore refuses a database that is not empty, boots the restored board and reads a seeded thread. The compose job also asserts the image carries the pg_dump the backup verb shells out to, and the Postgres services run 18 to match the shipped stack. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LYancK1YxtRYHHEmtoqRPA
The runner image ships postgresql-16 with a configured cluster, so /usr/bin/pg_dump is pg_wrapper resolving to 16 even after postgresql-client-18 is installed — and pg_dump 16 aborts against the 18 service. Prepend the 18 binaries via GITHUB_PATH and fail the setup step if version 18 is not what installed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LYancK1YxtRYHHEmtoqRPA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces
community backupandcommunity restorecommands that bundle database dumps and uploads together for consistent disaster recovery. It also upgrades the stack from Postgres 16 to Postgres 18 and adds the postgres client tools to the runtime image.Key Changes
New backup/restore system (
apps/cli/src/backup.ts):community backupcommand creates a single.tar.gzbundle containing apg_dump, uploads (local or S3), and a manifestcommunity restorecommand restores bundles into a new, empty database with uploadsDIRECT_DATABASE_URLfor dumps to avoid transaction pooler issuesS3FileStore enhancement (
packages/drivers/src/files/s3-file-store.ts):listKeys()async generator to paginate through all objects in a bucket--uploads includePostgres 18 upgrade:
postgres:16-alpinetopostgres:18-alpinepostgresql18-clientto the runtime Docker image sopg_dump,pg_restore, andpsqlare availableCLI integration (
apps/cli/src/index.ts):backupandrestorecommands with appropriate usage stringsComprehensive testing:
Documentation updates:
Notable Implementation Details
tar.gzandpg_dump --format=customfor portability and selective restorehttps://claude.ai/code/session_01LYancK1YxtRYHHEmtoqRPA