# Dokploy Postgres Backups: What Its Job Does When a Dump Fails

> A failed Dokploy run removes its partial dump only if the key can delete, per the v0.31.0 source. A full read caught what gzip -t passed in a simulation.

Published: 2026-11-06. Author: Milan Jovanović.

Canonical: https://milanjovanovic.tech/blog/dokploy-postgres-backup

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**](https://min.io/) 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):

```text
##### 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**](https://milanjovanovic.tech/blog/verify-pg-dump-backup) 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**](https://milanjovanovic.tech/blog/r2-bucket-lock-backups), 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**](https://milanjovanovic.tech/blog/off-site-backups-vps), 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:

```bash
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**](https://milanjovanovic.tech/blog/test-postgres-backup-restore), which expects a custom-format archive.

If you use the `pg-backup` script in my [**off-site backups guide**](https://milanjovanovic.tech/blog/off-site-backups-vps) 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:

```bash
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**](https://milanjovanovic.tech/blog/off-site-backups-vps) has a script that checks a dump before it uploads, and my [**self-hosting course**](https://milanjovanovic.tech/pragmatic-self-hosting) 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.
