Skip to main content
PostgreSQLAmazon S3
A backup you have never restored is a guess. In this tutorial you will connect an S3-compatible bucket, take a backup of a real Postgres database, schedule the next ones, delete data on purpose, and bring it back two ways: over the original database and into a brand-new copy.

Before you start

  • A running Levelrail instance and the CLI logged in to it (installing).
  • A Postgres database. Create main-db as in Connect an app to Postgres, or use your own.
  • A bucket and an access key pair with read and write access. AWS S3, Cloudflare R2, Backblaze B2, and MinIO all work.
1

Connect the bucket as a backup target

--provider is aws, r2, or custom. For r2 and custom, --endpoint is required; for aws it is not. Credentials are write-only: Levelrail never returns them after you save them.Test the connection now, so a bad key shows up today and not at 3am:
The Backups page, which asks for a backup target on a fresh install
2

Take a first backup

Put something in the database so you can tell whether a restore worked. The docker exec commands in this tutorial run on the server that hosts the database:
Then trigger a backup:
3

Schedule the rest

This takes a backup at 03:00 every day and keeps the newest seven. --retain-days prunes by age instead, and the two limits work independently. Setting a schedule replaces any earlier one for that database.
4

Verify the backup

Verification downloads the object again, recomputes its checksum, and compares size and format against what was recorded when the backup was taken. It also runs automatically after every backup.
5

Restore over the original

Simulate a mistake:
Restore from the backup. Restoring overwrites the database, so you must type its name to confirm:
The count is 2 again.
6

Restore into a new database

Overwriting is the right call when you are recovering. To inspect old data without touching the live database, restore into a copy:
Wait for the status to read succeeded, then query main-db-copy. The live database was never touched.
Older releasesUp to v0.2.0-beta.15, a restore into a new database could fail with database "..." does not exist because it started before the new Postgres had finished initializing. It is fixed in later releases. On an older one, delete the copy with levelrail-cli databases delete main-db-copy and run the restore again.

Clean up

Keep the target if you want to keep the schedule running.

Where to go next

Last modified on October 12, 2026