How to Back Up Nextcloud with Restic and Cron

Illustrative scenario (hypothetical): Jordan administers a small Nextcloud server on Ubuntu. The application files are in /var/www/nextcloud, user files are in /srv/nextcloud-data, MariaDB stores the Nextcloud database, and an off-site Linux host is available over SSH. Jordan wants a nightly backup that can be inspected and restored, not merely a cron entry that runs without errors.

This example gives Jordan a repeatable Restic and cron workflow. Paths, service accounts, database names, and schedule are examples; replace them with values from your installation. The commands do not imply that this setup was run or tested on a real server.

What a usable Nextcloud backup must contain

A folder copy by itself may omit the information Nextcloud needs to reconnect files, users, shares, and settings. The current Nextcloud 35 Administration Manual lists five items to retain: the configuration directory, custom apps if present, the data directory, the theme directory, and the database. The restore guide says the database, data directory, and configuration files are essential. Read the matching manual for your installed Nextcloud release before adapting the example.

Jordan chooses to back up the full application directory, which includes configuration, apps, and themes, plus the separate data directory and a database dump. A separate copy of each external storage location is also needed if Nextcloud stores user content outside /srv/nextcloud-data. Restic can only protect paths the backup process can read.

Nextcloud’s official backup instructions describe maintenance mode and database backups. Its restore instructions show why the database and file tree must come from a compatible recovery point.

1. Prepare Restic and its credentials

Install Restic from the package source you trust and confirm it is available to the account that will run the job. The sample assumes the job runs as root so it can read the Nextcloud files and database dump. It uses a remote SFTP repository so a failure of Jordan’s application server does not also erase the only backup copy.

restic version

install -d -m 700 /root/.config/restic
install -d -m 700 /root/.config/nextcloud

Create a strong Restic repository password and save it in /root/.config/restic/nextcloud-password with root-only permissions. Keep a secure recovery copy of that password somewhere separate from the server and repository. Restic encrypts repository data, but losing the password can make those encrypted backups unusable. Do not put the password directly in the script or cron line.

Configure noninteractive SSH access for the backup account on the remote host and verify its host key through a trusted channel. Set the repository location below to a directory that account can write:

export RESTIC_REPOSITORY='sftp:backup@vault.example.net:/srv/restic/nextcloud'
export RESTIC_PASSWORD_FILE='/root/.config/restic/nextcloud-password'
restic init

Initialize a repository only once. Restic’s repository preparation guide documents supported storage backends and initialization. Treat the password file and SSH key as sensitive credentials, and restrict access to them.

2. Keep the database and files at a compatible point

Nextcloud recommends maintenance mode for backups because it blocks new logins and locks existing sessions to prevent data inconsistencies. The command must run as the HTTP user; on a typical Ubuntu package setup that user is www-data. Jordan’s maintenance window lasts through the database dump and the Restic backup, so users cannot work in Nextcloud during that time.

For MariaDB, the Nextcloud manual uses mariadb-dump --single-transaction. Store database credentials in a protected client defaults file, for example /root/.config/nextcloud/mariadb.cnf, rather than embedding a password in the command:

[client]
user=nextcloud_backup
password=REPLACE_WITH_A_SECRET
host=localhost

Restrict the file with chmod 600 /root/.config/nextcloud/mariadb.cnf. Create a database account with only the privileges required by your server and dump procedure. If your Nextcloud uses PostgreSQL or SQLite, substitute its documented backup method; do not run the MariaDB command unchanged.

3. Create a guarded backup script

Jordan saves the following as /usr/local/sbin/nextcloud-restic-backup and makes it executable. It uses a lock to avoid overlapping runs, turns on maintenance mode before creating the dump, backs up the dump with the application and data directories, and attempts to turn maintenance mode off even if a later command fails.

#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

export RESTIC_REPOSITORY='sftp:backup@vault.example.net:/srv/restic/nextcloud'
export RESTIC_PASSWORD_FILE='/root/.config/restic/nextcloud-password'

NC_DIR='/var/www/nextcloud'
DATA_DIR='/srv/nextcloud-data'
DB_NAME='nextcloud'
DB_CNF='/root/.config/nextcloud/mariadb.cnf'
DUMP_DIR='/var/backups/nextcloud'
LOCK_FILE='/run/lock/nextcloud-restic-backup.lock'
STAMP=$(date -u +%Y%m%dT%H%M%SZ)
DUMP_FILE="$DUMP_DIR/nextcloud-$STAMP.sql"
maintenance_started=0

mkdir -p "$DUMP_DIR"
exec 9>"$LOCK_FILE"
flock -n 9 || { echo 'A Nextcloud backup is already running.' >&2; exit 1; }

finish() {
  result=$?
  trap - EXIT
  if [[ "$maintenance_started" == 1 ]]; then
    sudo -u www-data -- php "$NC_DIR/occ" maintenance:mode --off || result=1
  fi
  rm -f -- "$DUMP_FILE" || result=1
  exit "$result"
}
trap finish EXIT

sudo -u www-data -- php "$NC_DIR/occ" maintenance:mode --on
maintenance_started=1
mariadb-dump --defaults-extra-file="$DB_CNF" --single-transaction \
  --default-character-set=utf8mb4 --databases "$DB_NAME" > "$DUMP_FILE"
restic backup --tag nextcloud "$NC_DIR" "$DATA_DIR" "$DUMP_FILE"

After reviewing the paths, create the executable with root ownership and mode 700. The script assumes the installation uses www-data, MariaDB, and the listed paths; check these against config/config.php and your web server configuration first. It also assumes no other administrator has already enabled maintenance mode. If the command, dump, or Restic upload fails, the shell exits with an error and the trap attempts to restore service; check logs to confirm that happened. The dump is stored with restrictive permissions and removed after the run.

This simple pattern keeps the site unavailable for the entire Restic scan and upload. For a large data directory, that can be too long. Use a coordinated database dump and storage snapshot or another application-consistent backup design if your filesystem or storage platform supports it. Ensure the database and file snapshot represent a compatible point in time; independently copying a live database and a changing data directory can produce a backup that is difficult to restore.

4. Schedule the job with cron

Once a manual run has completed successfully, Jordan installs the script and schedules it for a quiet period. As root, edit the root crontab with sudo crontab -e and add:

15 2 * * * /usr/local/sbin/nextcloud-restic-backup >> /var/log/nextcloud-restic.log 2>&1

This example starts at 2:15 a.m. according to the server’s cron timezone; choose a time when the maintenance window is acceptable. Cron has a smaller environment than an interactive shell, so the script sets PATH explicitly and uses absolute paths. Create the log file with restrictive permissions and configure log rotation, or send output to your system’s normal logging service. Cron scheduling only starts the job: it does not confirm that the backup finished or that a restore will work.

5. Set retention and verify the result

After a successful backup, Jordan checks that a snapshot appears:

restic snapshots --tag nextcloud
restic check

restic check checks repository structure. A periodic restic check --read-data also reads stored data and can use substantial network and disk time, so schedule it according to repository size and recovery needs. Restic’s snapshot retention guide explains that forgetting snapshots and pruning unreferenced data are separate work, and that pruning locks the repository. Start with a dry run and a policy that matches your retention requirements:

restic forget --tag nextcloud --keep-daily 7 --keep-weekly 5 \
  --keep-monthly 12 --dry-run

Review the snapshots it proposes to remove. When satisfied, remove --dry-run and add --prune; run pruning when it will not collide with the nightly backup. These retention counts are an example, not a universal policy. Consider legal retention, available storage, and how far back you may need to recover.

The meaningful test is a restore drill. Restore a recent snapshot into a temporary directory on a separate system, not over Jordan’s live Nextcloud paths:

restic restore latest --tag nextcloud --target /tmp/nextcloud-restore-check

Confirm that the restored tree contains the expected configuration, data, and database dump, and inspect representative files. For a complete recovery exercise, follow the Nextcloud restore manual in an isolated environment and verify login, file access, and expected shares before relying on the procedure. Restic’s restore documentation describes selecting snapshots and restore targets.

How to tell when this approach needs to change

Jordan’s cron job is suitable only if the maintenance window fits the backup duration and every required data path is local and readable. Change the design when any of these signs appear:

  • The site remains in maintenance mode longer than users can tolerate: plan coordinated snapshots or another application-consistent method.
  • Logs show missing paths, permission errors, a failed database dump, or a nonzero Restic exit: fix those before treating the snapshot as complete.
  • Data lives in external storage or on another server: include a consistent backup of that storage in the recovery plan.
  • A test restore lacks files, configuration, database state, or required app/theme code: update the backup inputs and repeat the drill.
  • The Restic password or SSH credentials exist only on the server being backed up: store recovery credentials separately and verify that an authorized administrator can access them.

For Jordan, success is observable: the cron log shows a completed run, restic snapshots lists a recent tagged snapshot, repository checks report no errors, and a restore drill recovers a coherent Nextcloud instance. A scheduled command is the beginning of a backup routine; only a complete, restorable set of database, configuration, application, and user data provides a practical recovery path.

Official references

Leave a Comment

7 Best WSUS Tools for Update Management and Troubleshooting

7 Best WSUS Tools for Update Management and Troubleshooting

Compare seven tools that support or complement WSUS, from Microsoft’s native console and diagnostics to third-party patch publishing and remote deployment.

Best Windows System Monitoring Tools: 6 Picks for Server Visibility

Best Windows System Monitoring Tools: 6 Picks for Server Visibility

Compare six Windows system monitoring tools for server health, application visibility, and alerting, with current notes on deployment and licensing.

7 Wake-on-LAN Tools: What’s Still Available From the 2021 List

7 Wake-on-LAN Tools: What’s Still Available From the 2021 List

Compare seven Wake-on-LAN tools by features and availability, including free utilities, network-admin suites, and 2021 picks that have since been retired.

9 Best Ping Tools for Testing Latency and Scanning a Network

9 Best Ping Tools for Testing Latency and Scanning a Network

Compare nine ping tools for quick reachability checks, subnet discovery, TCP tests, and latency monitoring, with guidance on which one fits your network task.

Best TFTP Servers for Windows, Linux, and macOS

Best TFTP Servers for Windows, Linux, and macOS

Compare the best TFTP servers for Windows, Linux, and macOS, including SolarWinds, Tftpd64, tftpd-hpa, atftpd, haneWIN, and dnsmasq.

5 Best Microsoft Access Alternatives for Desktop and Web Databases

5 Best Microsoft Access Alternatives for Desktop and Web Databases

Compare five Microsoft Access alternatives for desktop, SQLite, no-code, and browser-based database work, with strengths, limits, and best-fit use cases.

Open-Source vs. Closed-Source Monitoring Tools Compared

Open-Source vs. Closed-Source Monitoring Tools Compared

Compare open-source and closed-source monitoring tools by cost, support, customization, security, and current options including Zabbix, Nagios, PRTG, and more.

Ingress vs. Egress: What’s the Difference in Networking?

Ingress vs. Egress: What’s the Difference in Networking?

Understand how ingress and egress describe incoming and outgoing traffic, why direction depends on the network boundary, and how to monitor bandwidth and spot risky data transfers.

6 Best Free Syslog Servers to Try for Centralized Logging

6 Best Free Syslog Servers to Try for Centralized Logging

Compare six free syslog servers and collectors for Windows and Linux, including GUI tools, open-source options, search, alerting, and secure transport.

What Is IIS? Microsoft’s Windows Web Server and Alternatives

What Is IIS? Microsoft’s Windows Web Server and Alternatives

See what Microsoft IIS does, how its request pipeline and application pools work, and when Apache, NGINX, or Caddy may fit your web server needs better.