Google Drive Backup#

This note documents the Google Drive mirror running on HP1Clouds (10.1.2.219) as observed on 2026-09-20. It is intended to make the setup reproducible on another VM.

This is a one-way Google Drive-to-local mirror, not a versioned or immutable backup. Google Drive is the source; the local VM copy is the destination.

The intended Google account is marc.ouellet@gmail.com. OAuth tokens and client credentials are intentionally excluded from this note.


1. Architecture#

Google Drive account
  rclone remote: MarcGoogleDocs:
             │
             │ hourly rclone sync
             ▼
HP1Clouds (10.1.2.219)
  /mnt/GoogleDocs  — local ext4 filesystem
             │
             ├── NFC filename normalization with convmv
             │
             └── Nextcloud AIO file scan
                   Marc/files/GoogleDocs

The root user’s cron launches the sync script every hour. The script downloads Google Drive files, exports native Google Workspace files to local formats, normalizes filenames, scans the result into Nextcloud, and fixes ownership for the web services.


2. Current VM Inventory#

Item Current value
Hostname HP1Clouds
IP address 10.1.2.219
Operating system Ubuntu 24.04, x86_64
Rclone binary /usr/bin/rclone
Rclone version observed v1.60.1-DEV
Docker Compose version observed v5.5.1
Filename normalizer /usr/bin/convmv
Rclone configuration /root/.config/rclone/rclone.conf
Rclone remote MarcGoogleDocs:
Local mirror /mnt/GoogleDocs
Local mirror filesystem ext4 on /dev/sdb
Nextcloud container nextcloud-aio-nextcloud
Script owner/mode root:root, 0755

The current filesystem reports approximately 3.9 GB total, 3.1 GB used, and 631 MB available. A replacement VM needs a sufficiently large local disk; this size should not be treated as a recommended capacity.

Current mount entry#

The current VM mounts the dedicated local disk using this entry in /etc/fstab:

UUID=f18e0c0c-1a38-4806-9582-d10b88adf27e  /mnt/GoogleDocs  ext4  defaults  0  2

The UUID is specific to the current disk. On another VM, create or attach the replacement disk, format it as ext4 if appropriate, obtain its UUID with blkid, and substitute the new UUID.


3. Required Directory Layout#

/home/marc/docker-compose/nextcloud-aio/
├── data/
├── logs/
│   ├── DB_Backups/
│   ├── Rclone/
│   └── file_indexer/
└── scripts/
    ├── Rclone-MarcGoogleDrive.sh
    └── file_indexer.sh

/mnt/GoogleDocs/

The Google Drive mirror must exist before the script runs:

mkdir -p /mnt/GoogleDocs
mkdir -p /home/marc/docker-compose/nextcloud-aio/scripts
mkdir -p /home/marc/docker-compose/nextcloud-aio/logs/Rclone

4. Rclone Remote#

The script expects a Google Drive remote named exactly MarcGoogleDocs:

MarcGoogleDocs:

The remote configuration is stored on the VM at:

/root/.config/rclone/rclone.conf

To reproduce the remote on another VM:

install -d -m 700 /root/.config/rclone
rclone config

Configure a Google Drive remote with:

Name:       MarcGoogleDocs
Storage:    drive
Account:    marc.ouellet@gmail.com

Authorize the account interactively or use a securely transferred, pre-authorized configuration. Do not place OAuth tokens, client secrets, or refresh tokens in this note or in Git.

Secure the resulting file:

chmod 600 /root/.config/rclone/rclone.conf

Verify only the remote name and access, without printing configuration values:

rclone listremotes
rclone lsd MarcGoogleDocs:

The current remote sees the personal Drive content and shared content available to that authorization. Reproduction must use the same account and equivalent Drive permissions if the same content set is required.


5. Exact Sync Script#

File:

/home/marc/docker-compose/nextcloud-aio/scripts/Rclone-MarcGoogleDrive.sh

Current script:

#!/bin/bash

# ===========================================================================
# SCRIPT: Rclone-MarcGoogleDrive.sh
# DESCRIPTION: Syncs Google Drive, fixes encoding, and indexes in Nextcloud
# LOCATION: /home/marc/docker-compose/nextcloud-aio/scripts/Rclone-MarcGoogleDrive.sh
# ===========================================================================

# --- CONFIGURATION ---
LOG_ROOT="/home/marc/docker-compose/nextcloud-aio/logs/Rclone"
DATE_FOLDER=$(date +%Y-%m-%d)
FILE_NAME="$(date +%Y-%m-%d_%H-%M)_RClone-MarcGoogleDrive.log"
FULL_LOG_PATH="$LOG_ROOT/$DATE_FOLDER"

# 1. Create the daily log folder
mkdir -p "$FULL_LOG_PATH"

# 2. Run the Sync with logging
# Using the new local disk mount at /mnt/GoogleDocs
rclone sync MarcGoogleDocs: /mnt/GoogleDocs \
  --local-encoding "None" \
  --drive-export-formats docx,xlsx,pptx,svg \
  --drive-acknowledge-abuse \
  --log-file="$FULL_LOG_PATH/$FILE_NAME" \
  --log-level INFO

# 3. Force NFC normalization on the disk
/usr/bin/convmv -r -f utf8 -t utf8 --nfc --notest /mnt/GoogleDocs/ \
  >> "$FULL_LOG_PATH/$FILE_NAME" 2>&1

# 4. Trigger Nextcloud indexing
sudo docker exec --user www-data nextcloud-aio-nextcloud \
  php occ files:scan --path="Marc/files/GoogleDocs" \
  >> "$FULL_LOG_PATH/$FILE_NAME" 2>&1

# 5. Delete log folders older than 7 days
find "$LOG_ROOT" -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf {} +

# 6. Fix permissions for Nextcloud
sudo chown -R www-data:www-data /mnt/GoogleDocs
sudo chmod -R 775 /mnt/GoogleDocs

Install and secure it on a replacement VM:

install -o root -g root -m 0755 /dev/null \
  /home/marc/docker-compose/nextcloud-aio/scripts/Rclone-MarcGoogleDrive.sh

# Place the script contents into the file, then verify its syntax:
bash -n /home/marc/docker-compose/nextcloud-aio/scripts/Rclone-MarcGoogleDrive.sh

The current script intentionally uses the exact remote name, local path, Nextcloud container name, and Nextcloud user path shown above.


6. Nextcloud AIO Integration#

The current nextcloud-aio-nextcloud container has the host’s /mnt directory bind-mounted at /mnt inside the container. This makes the host directory available to the occ scan command.

The relevant relationship is:

Host:      /mnt/GoogleDocs
Container: /mnt/GoogleDocs
Nextcloud: Marc/files/GoogleDocs

The container must be named nextcloud-aio-nextcloud, or the docker exec target in the script must be changed. The Nextcloud account must be named Marc, or the --path value must be changed.

The VM also runs an owncloud_server container with /mnt/GoogleDocs mounted, but the sync script indexes the files into Nextcloud AIO specifically.

The existing general Nextcloud documentation is in NextCloud. Do not copy passwords or mail credentials from that note into this setup note.


7. Scheduling#

There is no dedicated systemd unit for this mirror. It is scheduled from root’s crontab:

0 * * * * /home/marc/docker-compose/nextcloud-aio/scripts/Rclone-MarcGoogleDrive.sh > /dev/null 2>&1

Install it on a replacement VM with:

crontab -e

Then add the line above. Confirm it is present:

crontab -l

The separate go-cron process and nextcloud-db-backup container observed on the VM are part of other Nextcloud/AIO functions; they are not the Google Drive mirror.


8. Logging and Monitoring#

Rclone, filename normalization, and Nextcloud scan output are written to:

/home/marc/docker-compose/nextcloud-aio/logs/Rclone/YYYY-MM-DD/YYYY-MM-DD_HH-MM_RClone-MarcGoogleDrive.log

The script removes daily log directories older than seven days.

Useful read-only checks:

findmnt -T /mnt/GoogleDocs
df -hT /mnt/GoogleDocs
rclone listremotes
crontab -l

docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}'

find /home/marc/docker-compose/nextcloud-aio/logs/Rclone \
  -type f -name '*_RClone-MarcGoogleDrive.log' -print | sort | tail

For a safe preflight without writing changes:

rclone sync --dry-run MarcGoogleDocs: /mnt/GoogleDocs \
  --local-encoding "None" \
  --drive-export-formats docx,xlsx,pptx,svg \
  --drive-acknowledge-abuse

To run one normal synchronization manually:

bash /home/marc/docker-compose/nextcloud-aio/scripts/Rclone-MarcGoogleDrive.sh

9. Current Operational State and Known Issues#

As of 2026-09-20:

  1. The hourly job is running and producing timestamped logs.
  2. Some runs report There was nothing to transfer, indicating no detected content changes for those runs.
  3. Other runs fail while listing Google Drive directories with HTTP 403 errors caused by the Google Drive API queries-per-minute quota.
  4. The latest inspected run transferred no data and ended with five errors after approximately 16 minutes.
  5. When errors occur, rclone reports that it will not delete local files or directories. This is a safety behavior during the failed run, not a configured versioning policy.
  6. The local filesystem is already approximately 84% full.
  7. The installed Rclone build is v1.60.1-DEV; compatibility and upgrade strategy should be reviewed separately.

The API quota problem is intentionally not addressed in this note. It is a follow-up task.


10. Backup Characteristics and Limitations#

This setup provides a local working copy of Google Drive files, but it does not provide:

  • historical file versions;
  • immutable or append-only retention;
  • a configured recycle-bin or deletion archive;
  • encryption of the local mirror;
  • a documented backup of Google Drive permissions, comments, sharing metadata, or revision history;
  • a second copy of /mnt/GoogleDocs on another host or storage system.

The --drive-export-formats option converts native Google Docs, Sheets, and Slides into local file formats. The exported files are useful for recovery, but they should not be assumed to preserve all Google Workspace metadata or revision history.

The separate nextcloud-db-backup container backs up the Nextcloud PostgreSQL database locally. It does not create a second backup of the Google Drive mirror itself.


11. Reproduction Checklist#

  • Provision an Ubuntu VM with enough local storage for the complete mirror plus growth.
  • Install Docker, Docker Compose, Rclone, and convmv.
  • Deploy or restore Nextcloud AIO and confirm the nextcloud-aio-nextcloud container.
  • Attach and mount a local filesystem at /mnt/GoogleDocs.
  • Ensure the Nextcloud container can see host /mnt as container /mnt.
  • Create the MarcGoogleDocs Google Drive remote using OAuth for marc.ouellet@gmail.com.
  • Protect /root/.config/rclone/rclone.conf with mode 600.
  • Install the sync script at the documented path with mode 0755.
  • Confirm the Nextcloud user/path used by occ files:scan.
  • Add the hourly root cron entry.
  • Run bash -n and an rclone --dry-run preflight.
  • Run one manual synchronization and verify the log.
  • Confirm /mnt/GoogleDocs ownership is www-data:www-data and mode 775.
  • Check available disk capacity before enabling continuous scheduling.
  • Resolve the deferred Google Drive API quota issue before treating the mirror as reliable.