Skip to content

Dockup reads dockup.* labels from two places:

  • named volumes — the volume is the source, so its policy is flat;
  • containers — a container may expose several host paths, so bind sources are grouped by a name, and container-level labels decide whether the container may be stopped or has hooks.

Nothing is backed up unless it opts in. Labels are read on every Docker event and on a periodic resync, so changes to containers are picked up live. Named volume labels are immutable in Docker: recreate the volume to change them.

Named volumes ​

yaml
volumes:
  appdata:
    labels:
      dockup.enable: "true"
      dockup.schedule: daily
      dockup.target: nas,offsite
      dockup.keep-daily: "7"
      dockup.keep-monthly: "6"
      dockup.encrypt: "true"
LabelTypeDefaultDescription
dockup.enablebooleanfalseOpt in. Without it the volume is ignored.
dockup.schedulestringdefaults.scheduleA name from schedules, or an inline cron expression (0 3 * * *, @daily, @every 6h).
dockup.targetlistdefaults.targetsComma separated target names. Unknown names are an error.
dockup.filenamestring{source}_{timestamp}Archive base name. Placeholders: {source}, {volume}, {bind}, {host}, {schedule}, {timestamp}.
dockup.compressionenumzstdnone, gzip, zstd.
dockup.encryptbooleandefaults.encryptEncrypt with encryption.age.recipients.
dockup.verifybooleandefaults.verifyRe-read the uploaded archive and compare its checksum.
dockup.catch-upbooleandefaults.catch-upRun a backup at startup when the last successful run is older than the upcoming interval.
dockup.keep-lastintegerdefaults.keep-lastKeep the newest N archives.
dockup.keep-dailyintegerdefaults.keep-dailyKeep the newest archive of each of the newest N days.
dockup.keep-weeklyintegerdefaults.keep-weeklySame, per ISO week.
dockup.keep-monthlyintegerdefaults.keep-monthlySame, per calendar month.
dockup.max-agedurationdefaults.max-ageHard cap (7d, 36h, 4w). The newest archive is never pruned.
dockup.excludelist—Relative paths or globs to skip, e.g. cache,*.log.

Retention is disabled when every keep value and max-age are zero: Dockup then never deletes anything.

dockup.stop, dockup.hook and dockup.bind.* are container-only; using them on a volume is reported as a warning.

Containers: bind mounts ​

A container declares each host path it exposes with dockup.bind.<name>, then configures it with dockup.<name>.<option> using the same options as volumes:

yaml
services:
  app:
    labels:
      # sources
      dockup.bind.data: /srv/app/data
      dockup.bind.config: /srv/app/config
      # per-source policy (optional)
      dockup.data.schedule: hourly
      dockup.data.target: offsite
      dockup.data.keep-last: "48"
      # container-level defaults for every bind source above
      dockup.schedule: daily
      dockup.target: nas
      # quiescing
      dockup.stop: "true"
      dockup.hook: postgres
LabelDescription
dockup.bind.<name>Absolute host path to archive. Required to declare a source.
dockup.<name>.<option>Any option from the volume table (schedule, target, filename, compression, encrypt, verify, keep-*, max-age, exclude), plus enabled.
dockup.<option>Container-level default for all bind sources of this container.
dockup.stoptrue allows Dockup to stop this container while its sources are archived, then start it again.
dockup.hookName of a hook set from hooks in the configuration. Commands run inside this container.

Notes:

  • Bind source names must not be stop, hook or bind.
  • The archive identity of a bind source is its host path, not the source name, so recreating a container keeps its archive history and retention.
  • When two containers declare the same path with different policies, Dockup keeps the first (sorted by container name), merges the containers for quiescing and reports a warning.
  • / is rejected: refusing to archive the host root is a feature.

Quiescing ​

A backup of a live database can capture a half-written state. Dockup only touches containers that opt in:

  1. Hooks first — containers with dockup.hook=<name> run the hook set's pre commands (sh -c) before anything is stopped, so a pg_dump can write into the volume that is about to be archived.
  2. Then stop — containers with dockup.stop=true that mount (volume sources) or declare (bind sources) the source are stopped, and started again once the archive is finished (or has failed). stop-timeout (default 30s) is the grace period before Docker kills them.
  3. Then archive, and finally run the post commands — also when the archive failed, so temporary dumps are always cleaned up.

If a pre command fails, nothing is stopped and the run is recorded as failed.

A container without either label is never touched, even if it mounts the volume.

Naming and layout ​

Archives are stored per source and schedule:

<target prefix>/<host>/volume/<volume>/<schedule>/<filename>.tar.zst[.age]
<target prefix>/<host>/bind/<host path>/<schedule>/<filename>.tar.zst[.age]

The default prefix is dockup, the host defaults to the container hostname. Every archive name carries a UTC timestamp, which is what retention uses to bucket archives: Dockup appends _<timestamp> unless the filename template already contains {timestamp}.

Released under the Mozilla Public License 2.0.