Dokploy v0.31.0 handles a failed Postgres dump only in part.
A failed run removes its partial object if the key can delete, and a key that can't leaves a cut object that gzip -t and pg_restore --list accept.
This comes from its source and a simulation, and I didn't install Dokploy.
Does Dokploy Handle a Failed Postgres Backup?
Partly, going by its source. I read the Dokploy v0.31.0 source and ran shell rendered from its backup template in a simulation. Its UI, job queue, notifications, and restore flow are untested. The simulation ran on MinIO in a lab under WSL2, with PostgreSQL 18.6 and rclone 1.75.2, never on a real provider.
| Part | Per its v0.31.0 source |
|---|---|
| Dump | pg_dump -Fc --no-acl --no-owner through gzip into rclone rcat, with pipefail, so its dumps hold no grants or owners |
| Failed run | Runs rclone deletefile with errors ignored, sends an error notification, exits 1, skips retention |
| Keep Latest | Counts objects without checking them |
| Standalone databases | Run as Swarm services, so a filter on Compose labels finds nothing |
| The .sql.gz name | Holds a gzipped custom archive |
| Object key | <appName>/<prefix>/<file>, so the app name comes before the prefix you typed |
On the rendered shell, I ended the dump with pg_terminate_backend.
A key that could delete removed the partial object, and a key that couldn't left this (trimmed):
##### v0.31.0, same failure, key that can list, read and write but NOT delete
exit status of the generated script: 1
79751699 2026-11-05 14:48:08.909893471 2026-11-05T14-48-08-833Z.sql.gz
gzip -t exit 0
gunzip | pg_restore --list exit 0
gunzip | pg_restore -f /dev/null exit 1 pg_restore: error: could not read from input file: end of file
The object passed gzip -t and pg_restore --list, and only the full read rejected it.
My comparison of dump checks has more cases.
In the simulation, Keep Latest kept a truncated object over a good one. That object came from the older v0.29.14 template, which has no delete step, and I didn't repeat this with an object left by v0.31.0.
Under an R2 bucket lock, I'd expect a failed Dokploy run to leave its partial object, because the delete would be refused. That is an inference from Dokploy's source and Cloudflare's docs, and nobody ran it.
How Do I Check a Dokploy .sql.gz Backup?
These commands assume the offsite rclone remote and RCLONE_CONFIG from my off-site backups guide, with the remote pointed at your Dokploy S3 destination.
Replace shop-backups with its bucket and <CHANGE-DOKPLOY-PREFIX> with the database's app name, followed by the job's prefix if it has one, because per the v0.31.0 source a standalone database's key is <appName>/<prefix>/<file>.
<CHANGE-APP-NAME> is that same app name, which is the database's Swarm service name, and the docker ps line in that guide shows it in column 4.
You also need jq.
psql refused an object I made with Dokploy's pipeline, so check a .sql.gz this way:
prefix=offsite:shop-backups/<CHANGE-DOKPLOY-PREFIX>
pg=$(docker ps -q --filter label=com.docker.swarm.service.name=<CHANGE-APP-NAME>)
newest=$(rclone lsjson --files-only --use-server-modtime "$prefix" | jq -r 'sort_by(.ModTime) | last | .Path')
rclone cat "$prefix/$newest" | gunzip | docker exec -i "$pg" pg_restore -f /dev/null; echo "${PIPESTATUS[*]}"
rclone cat "$prefix/$newest" | gunzip | docker exec -i "$pg" pg_restore --list | grep -c ' TABLE DATA '
The output was 0 0 0 and 3.
If you keep Dokploy's job, I'd run those two checks against its newest object on a schedule, because a failed run can leave a partial object behind.
To restore one, gunzip it first and follow my restore drill, which expects a custom-format archive.
If you use the pg-backup script in my off-site backups guide instead, its default Compose filter finds nothing on a standalone database, so its filter line becomes this, which I tested only on a plain Swarm service:
pg_filters=(--filter label=com.docker.swarm.service.name=<CHANGE-APP-NAME>)
Summary
Per its v0.31.0 source, a failed Dokploy run deletes its object only if the key can, and Keep Latest counts objects without checking them.
With a key that couldn't delete, the rendered shell left a cut object that gzip -t and pg_restore --list accepted, so run the two checks above against the newest object.
All of this comes from the source and a simulation on MinIO, and I didn't install Dokploy. Run a failed backup on your real server and provider before you count on it.
My off-site backups guide has a script that checks a dump before it uploads, and my self-hosting course sets up database backups to storage outside the server.
Thanks for reading.
And stay awesome!
Frequently Asked Questions
What happens when a Dokploy Postgres backup fails?
Per its v0.31.0 source, it runs rclone deletefile with errors ignored, sends an error notification, exits 1, and skips retention. On rendered shell, a key that could not delete left the partial object. I did not install Dokploy.
Why does psql refuse a Dokploy .sql.gz backup?
Per the v0.31.0 source, the .sql.gz name holds a gzipped custom archive. psql refused an object I made with that pipeline, so read it with gunzip and pg_restore. Dokploy did not make that object, and I did not run its restore flow.
Does Dokploy Keep Latest check the backups it keeps?
Per its source, it counts objects without checking them. In a simulation, Keep Latest kept a truncated object from the older v0.29.14 template over a good one, and I did not repeat this with an object left by v0.31.0.

