Skip to content

Nextcloud ​

Nextcloud spreads its state across a volume (user files) and a database. Files are written by PHP workers, so a hot tar can capture a file that is still being written — but Nextcloud tolerates that as long as you restore files and database together.

Compose file ​

yaml
services:
  nextcloud:
    image: nextcloud:30
    volumes:
      - nextcloud-data:/var/www/html
    labels:
      dockup.stop: "true"
    depends_on: [db]

  db:
    image: mariadb:11
    environment:
      MARIADB_ROOT_PASSWORD_FILE: /run/secrets/db-root
      MARIADB_DATABASE: nextcloud
    volumes:
      - nextcloud-db:/var/lib/mysql
    labels:
      dockup.stop: "true"
      dockup.hook: mariadb

volumes:
  nextcloud-data:
    labels:
      dockup.enable: "true"
      dockup.schedule: daily
      dockup.target: nas,offsite
      dockup.keep-daily: "7"
      dockup.keep-weekly: "4"
      dockup.keep-monthly: "6"
      dockup.max-age: "400d"
      # Thumbnails and logs are regenerable.
      dockup.exclude: "var/log,var/tmp,*/appdata_*/preview,updater-*"
      dockup.encrypt: "true"

  nextcloud-db:
    labels:
      dockup.enable: "true"
      dockup.schedule: daily
      dockup.target: nas,offsite
      dockup.keep-daily: "7"
      dockup.encrypt: "true"
yaml
# dockup.yml
hooks:
  mariadb:
    pre:
      - mariadb-dump --single-transaction --quick --databases nextcloud -r /var/lib/mysql/dockup.sql
    post:
      - rm -f /var/lib/mysql/dockup.sql

Why both containers are stopped ​

dockup.stop: "true" on the app keeps PHP from writing to nextcloud-data mid-archive; the same label on db keeps MariaDB from writing to its volume. Dockup only stops containers that mount or declare the source being archived, so backing up nextcloud-data stops nextcloud, and backing up nextcloud-db stops db.

Order matters for restores, not for backups

Restore the database first, then the data volume, and start Nextcloud last. The files carry a maintenance flag in config/config.php; if Nextcloud complains after a restore, put it into maintenance mode once and let it finish:

console
$ docker compose run --rm nextcloud occ maintenance:mode --on
$ docker compose run --rm nextcloud occ maintenance:repair
$ docker compose run --rm nextcloud occ maintenance:mode --off

Excluding what can be rebuilt ​

dockup.exclude takes a comma-separated list of relative paths or globs. For Nextcloud the interesting ones are previews, logs and the updater's staging directory — often the bulk of the volume and all of it regenerable.

Check what a pattern really matches before relying on it:

console
$ docker compose run --rm dockup restore --source volume:nextcloud-data --dry-run | head -40

The dry run lists the entries of the newest archive without writing anything.

Released under the Mozilla Public License 2.0.