Backup NextCloud data to Dropbox
Tags: nextcloud, dropbox, devops
Published: 2019-07-05 23:04:03

Dropbox is the primary cloud sync provider in my family. All our personal documents, family photographs, code projects etc. live there. Folder common to both my wife and I are shared between our accounts. Everything else remains separate. We also backup the data to external hard drives. My personal MacBook also uses Backblaze. We overdo our backup strategy due to a data loss incident couple of years back.

We also have Nextcloud on a Debian system in our home network. It suffices as our media centre.  I wanted to create a backup system for the Nextcloud installation. I didn’t want to use S3 or anything else at this point as our Nextcloud instance is not a huge data hog. So I am using my existing Dropbox instance for this. Nextcloud allows Dropbox to be used as an external storage. But I use my local HDD as the storage for Nextcloud and then rsync it to a Dropbox folder.

## Initial setup for Dropbox

1. On the host machine (where Nextcloud is installed), install Dropbox. This process will vary based on your operating system. 
2. Create a folder “NEXTCLOUD-BKP” in Dropbox. Make it a shared folder if required. 
3. Using the Selective Sync feature remove all other folders except the newly created one. Since the primary purpose of my Debian system is Nextcloud, I am only syncing the backup folder for Dropbox and not any other data.
4. This step is specific for my setup. My Nextcloud instance uses Apache web server and runs as _www-data_ user. But my Dropbox is installed as the main logged in user. In order to enable me to copy the data owned by _www-data_ user, add the logged in user to _www-data_ group. `usermod -a -G www-data <LOGGED_IN_USER>`. Make the permissions of the “NEXTCLOUD-BKP” folder to g+rwx. `chmod g+rwx ~/Dropbox/NEXTCLOUD-BKP`. Ensure that the Dropbox and “NEXTCLOUD-BKP” folder has “x” bit set to enable the _www-data_ user to copy to its subfolders. [https://askubuntu.com/questions/455000/group-permissions-allow-but-still-get-permission-denied](https://askubuntu.com/questions/455000/group-permissions-allow-but-still-get-permission-denied "Stackoverflow link")

## Enable maintenance mode on Nextcloud
This locks the sessions of existing logged in users to prevent inconsistency in the database. It also prevents new logins. `php $NEXTCLOUD_PATH/occ maintenance:mode --on`.

## Copy the Nextcloud data using rsync
You can either copy the whole Nextcloud folder or just the data, config and themes folder.
```bash
rsync -Aavx $NEXTCLOUD_PATH/data ~/Dropbox/NEXTCLOUD-BKP
rsync -Aavx $NEXTCLOUD_PATH/config ~/Dropbox/NEXTCLOUD-BKP
rsync -Aavx $NEXTCLOUD_PATH/themes ~/Dropbox/NEXTCLOUD-BKP
```

## Backup Nextcloud database
My Nextcloud database is MariaDB. If you use PostgreSQL or SQLite, then this step will be different for you.
```bash
# Database name is nextcloud
/usr/bin/mysqldump --defaults-extra-file=$MYSQL_CREDENTIALS_FILE --single-transaction --databases nextcloud > ~/Dropbox/NEXTCLOUD-BKP/database/nc-db-bkp_`date +"%Y-%m-%d-%H-%M"`.bak
```

The `$MYSQL_CREDENTIALS_FILE` provides the username and password for the next cloud database. [https://dev.mysql.com/doc/refman/5.5/en/option-files.html](https://dev.mysql.com/doc/refman/5.5/en/option-files.html "MySQL documentation for extra files") `nextcloud` is the name of the database.

## Update permissions of the backup folders created/updated
This step will depend on your setup and might be completely optional. Since I have different user running nextcloud, I need to do this for Dropbox to read the newly created files.
```bash
chmod -R 777 $DROPBOX_NEXTCLOUD_PATH/data
chmod -R 777 $DROPBOX_NEXTCLOUD_PATH/config
chmod -R 777 $DROPBOX_NEXTCLOUD_PATH/themes
chmod -R 777 $DROPBOX_NEXTCLOUD_PATH/database
```
Since my installation is within my home network and is behind a firewall and opens only the required ports, I feel safe doing the above. YMMV.

## Disable maintenance mode on Nextcloud
Once all the above steps are done, disable the maintenance mode. `php $NEXTCLOUD_PATH/occ maintenance:mode --on`.

## Setup a cron
I run the script once a day at 9PM. `0 21 * * * nextcloud-backup.sh`. The script must run as the _www-data_ user or the user running the nextcloud process. Here is the complete script.

```bash
#!/usr/bin/env bash

# Can set the below three as environment variables or uncomment to set actual paths
NEXTCLOUD_PATH=<NEXTCLOUD_INSTALLATION_PATH>
DROPBOX_NEXTCLOUD_PATH=<PATH_TO_NEXTCLOUD_BACKUP_FOLDER_IN_DROPBOX>
MYSQL_CREDENTIALS_FILE=<MYSQL_CREDENTIALS_FILE_CONF_FORMAT>

PHP_PATH=`which php`
MYSQLDUMP_PATH=`which mysqldump`
# Enable Maintenance mode
$PHP_PATH $NEXTCLOUD_PATH/occ maintenance:mode --on

# Backup data, config and themes from nextcloud directory.
# Can sync the entire nextcloud directory if needed
rsync -Aavx $NEXTCLOUD_PATH/data $DROPBOX_NEXTCLOUD_PATH
rsync -Aavx $NEXTCLOUD_PATH/config $DROPBOX_NEXTCLOUD_PATH
rsync -Aavx $NEXTCLOUD_PATH/themes $DROPBOX_NEXTCLOUD_PATH

# Backup MySQL
$MYSQLDUMP_PATH --defaults-extra-file=$MYSQL_CREDENTIALS_FILE --single-transaction --databases nextcloud > $DROPBOX_NEXTCLOUD_PATH/database/nc-db-bkp_`date +"%Y-%m-%d-%H-%M"`.bak

# Update permissions of the backup path to 777 (Because the user running nextcloud is different.)
chmod -R 777 $DROPBOX_NEXTCLOUD_PATH/data
chmod -R 777 $DROPBOX_NEXTCLOUD_PATH/config
chmod -R 777 $DROPBOX_NEXTCLOUD_PATH/themes
chmod -R 777 $DROPBOX_NEXTCLOUD_PATH/database

# Disable Maintenance mode
$PHP_PATH $NEXTCLOUD_PATH/occ maintenance:mode --off
```


This provides a good setup for me and my Nextcloud data is backed up to Dropbox. Please note that the `mysqldump` is not incremental. So you might need to delete older files if required. I keep 5 days backup only as the actual data folder is completely overwritten by `rsync`. You can update the `rsync` commands by creating an archive and saving instead of actual copy.

_Originally published on [Shubho.Dev](https://www.shubho.dev/blog/backup-nextcloud-data-to-dropbox)_

Featured Image courtesy [Dirk Wouters](https://pixabay.com/users/www_darkworkx_de-2044000/) at Pixabay