SafeGrd / DigitalOcean Postgres backup

How to back up a DigitalOcean Managed PostgreSQL cluster, past its 7 days

DigitalOcean backs up a managed PostgreSQL cluster once a day and keeps seven days, with a restore to a point in time that makes a new cluster. It keeps no backup longer than that and gives you no file. This page is the dump you keep: the host to connect to, the role, the command, where the file goes, the restore and the check, plus the one thing to know about Spaces as the destination. The last section is how SafeGrd runs it from a droplet in the VPC.

What DigitalOcean's backups cover

From DigitalOcean's documentation, read on 2026-10-08:

1. Reach the cluster

The cluster's Connection Details show a public hostname and, for anything in the same VPC, a private one. Both use the port the panel shows, and the string ends in sslmode=require:

postgresql://backup:PASSWORD@db-postgresql-fra1-12345-do-user-67890-0.c.db.ondigitalocean.com:PORT/defaultdb?sslmode=require

Make a role for the backup that can read and cannot write. doadmin can create it:

CREATE ROLE backup LOGIN PASSWORD 'a long random password';
GRANT pg_read_all_data TO backup;

2. Dump it

pg_dump --format=custom --no-owner --no-privileges --file=do.dump "$DATABASE_URL"

The client has to be at least the cluster's major version, shown on the cluster's overview. --no-owner --no-privileges keeps doadmin and DigitalOcean's grants out of the dump, so it restores anywhere. A cluster with several databases is one dump each.

3. Off the account, encrypted, on a schedule

# /etc/cron.d/pg-backup on a droplet in the VPC: 02:15 UTC every night
15 2 * * * backup /usr/local/bin/pg-backup.sh >> /var/log/pg-backup.log 2>&1
# pg-backup.sh
set -euo pipefail
pg_dump -Fc --no-owner --no-privileges "$DATABASE_URL" | age -r "$AGE_RECIPIENT" | aws s3 cp - "s3://$BUCKET/do/$(date -u +%F).dump.age"

Where the bucket is matters. DigitalOcean Spaces is S3-compatible and the obvious choice from a droplet, and it has no Object Lock: anyone with the Spaces key can delete every backup in it. For a copy nobody can delete early, use a bucket with Object Lock at another provider, in an account that is not the one the droplet's keys reach: which providers have it, and how to set one up. If Spaces is where it has to go, give the droplet a key that can write and not delete, and keep a second copy elsewhere. The S3 guide has the full script and the policy.

4. Restore, and check it

Into a new DigitalOcean cluster, or any PostgreSQL of the same or a newer major version: create an empty database and restore into it, stopping at the first error. A new cluster needs any extension the dump names to be on DigitalOcean's supported list.

aws s3 cp "s3://$BUCKET/do/2026-10-08.dump.age" - | age -d -i backup-key.txt > do.dump
pg_restore --exit-on-error --no-owner --no-privileges --dbname "$RESTORE_URL" do.dump

Then compare row counts per table with the source, as How to test that a backup restores shows.

How SafeGrd does it

SafeGrd's daemon runs on a droplet in the VPC, from the install script or the ghcr.io/safegrd/cli image, and reads the cluster over the private hostname. A sandbox drill loads the backup into a PostgreSQL server on the droplet: the image carries one, and a droplet set up by the install script needs one installed. SafeGrd does the same job on every platform; the PostgreSQL page has what it dumps, how it encrypts, and what a drill checks.

Run your first Fire Drill Read the install guide

curl -fsSL https://safegrd.dev/install.sh | sh
safegrd enroll
safegrd backup --database-url "$DATABASE_URL" --retention-days 14

Spaces works as a sink with the lock turned off in the config, stated as worm_mode: "NONE", and the console says so on every backup written there (Spaces, and any bucket without Object Lock). With no droplet, Back up on SafeGrd under Surfaces in the console takes the public connection string; a machine SafeGrd starts for each backup dumps and encrypts it, then is destroyed, and the string is sealed and given only to that machine (how). Where SafeGrd's machines connect from fixed addresses, the console shows them, for the cluster's trusted sources.

Questions

Does this replace DigitalOcean's backups?

No. The daily backup and the point-in-time restore are the quick undo for the last week, and they come with the cluster. The dump is for anything older, and for after the cluster or the account is gone.

Can I back up from a standby node?

Yes, where the plan offers read-only connections to a standby. Point the connection string at it to keep the read off the primary; the dump is the same.

Related