A full Nextcloud recovery has to bring application files and database rows back to the same point in time. That matters after a failed server, bad upgrade, storage loss, or migration rollback where ordinary file recovery is not enough.
The restore set must come from one recovery point. Mixing a newer database with older user files, or an older config with newer app files, can leave file indexes, app settings, and sync clients disagreeing about the recovered state.
Use a disposable restore target when possible, and keep public traffic blocked until the recovered instance passes its checks. The target environment uses a MariaDB database and a Linux install under /var/www/nextcloud; replace paths, database names, and the web-server user to match the server being recovered.
Related: How to create a Nextcloud backup
Related: How to run Nextcloud occ commands
The set should contain the Nextcloud configuration directory, data directory, database dump, and any custom themes from the same recovery point. Example paths used below are under /srv/backups/nextcloud.
$ cd /var/www/nextcloud
Use the directory that contains the occ file. Archive, package, and container installs can use different web-root paths.
$ sudo -E -u www-data php occ status --output=json_pretty
{
"installed": true,
"version": "33.0.5.1",
"versionstring": "33.0.5",
"edition": "",
"maintenance": false,
"needsDbUpgrade": false,
"productname": "Nextcloud",
"extendedSupport": false
}
Replace www-data with the HTTP user used by the server.
$ sudo -E -u www-data php occ maintenance:mode --on Maintenance mode enabled
If the old instance cannot run occ, block web access at the proxy, firewall, or service layer before restoring. User writes during restore can mix old and recovered state.
$ sudo rsync -a --delete /srv/backups/nextcloud/config/ /var/www/nextcloud/config/
The --delete option removes destination files that are not in the selected backup. Confirm the source path before running it.
$ sudo rsync -a --delete /srv/backups/nextcloud/data/ /var/www/nextcloud/data/
Do not restore over a data directory that contains newer production uploads unless the recovery decision explicitly discards those changes.
$ sudo rsync -a --delete /srv/backups/nextcloud/themes/ /var/www/nextcloud/themes/
Skip this step when the instance never used custom themes or the full installation directory was restored as one unit.
$ sudo -E -u www-data php occ maintenance:mode --on Maintenance mode enabled
A restored /config/config.php can contain the backup's old maintenance value, so set the lock again before rebuilding the database.
$ mariadb -h db.example.com -u dbadmin -p -e "DROP DATABASE nextcloud; CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'app.example.com'; FLUSH PRIVILEGES;" Enter password:
Dropping the wrong database destroys live data. Confirm the host, database name, and restore target before running the command.
$ mariadb -h db.example.com -u nextcloud -p nextcloud < /srv/backups/nextcloud/db/nextcloud.sql Enter password:
Add --default-character-set=utf8mb4 when the backup was created from a MariaDB setup that uses Nextcloud's 4-byte support.
$ sudo -E -u www-data php occ maintenance:data-fingerprint Updated data-fingerprint to b8a2bebb54aa14aac45cf84f4b10c956
maintenance:data-fingerprint tells sync clients that server-side data changed outside their normal sync path.
$ sudo -E -u www-data php occ maintenance:mode --off Maintenance mode disabled
files:scan is unavailable while maintenance mode is on because app commands are not loaded. Keep public traffic blocked until the scan and smoke test pass.
$ sudo -E -u www-data php occ files:scan --all Starting scan for user 1 out of 1 (admin) +---------+-------+-----+---------+---------+--------+--------------+ | Folders | Files | New | Updated | Removed | Errors | Elapsed time | +---------+-------+-----+---------+---------+--------+--------------+ | 5 | 64 | 0 | 0 | 0 | 0 | 00:00:00 | +---------+-------+-----+---------+---------+--------+--------------+
Large installations can take much longer. Use a specific user ID instead of --all when only one user's externally restored files need indexing.
Related: How to scan files with Nextcloud occ
$ sudo -E -u www-data php occ status --output=json_pretty
{
"installed": true,
"version": "33.0.5.1",
"versionstring": "33.0.5",
"edition": "",
"maintenance": false,
"needsDbUpgrade": false,
"productname": "Nextcloud",
"extendedSupport": false
}
$ curl -sS https://cloud.example.com/status.php
{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"33.0.5.1","versionstring":"33.0.5","edition":"","productname":"Nextcloud","extendedSupport":false}
After the endpoint returns the expected state, sign in as a normal user and open a known restored file before declaring the recovery complete.