# Set up automated backups to Quake AI

Source: https://docs.quake.ai/docs/quickstart/automated-backups
Markdown: https://docs.quake.ai/docs/quickstart/automated-backups.md

---

# Set up automated backups to Quake AI

In this walkthrough, you build a complete backup pipeline that copies your project files to Quake AI object storage on a schedule. By the end, you will have rclone configured as a Quake AI remote, an encrypted backup repository powered by restic, a cron job running daily backups, and a tested restore procedure that proves your backups work.

**What you will learn:**

- Why off-site backups matter and how the 3-2-1 rule protects your data
- How to install and configure rclone to work with Quake AI's S3-compatible storage
- How to run your first backup and verify the files arrived
- How restic adds encryption and deduplication on top of object storage
- How to schedule automatic daily backups with cron
- How to restore files from a backup: the step most backup guides skip

**Time estimate:** 30–40 minutes

<Figure size="md" caption="What you'll build: a cron schedule drives restic, which encrypts and dedupes before rclone uploads to a Quake AI bucket">

```mermaid
flowchart LR
    accTitle: Automated backup pipeline to Quake AI object storage
    accDescr: A daily cron job triggers restic, which encrypts and deduplicates files, then sends them through rclone to a Quake AI S3-compatible bucket

    cron[cron schedule<br/>daily]
    files[Local files]
    restic[restic<br/>encrypt + dedupe]
    rclone[rclone<br/>S3 client]
    bucket[(Quake AI<br/>bucket)]

    cron --> restic
    files --> restic
    restic --> rclone
    rclone --> bucket
```

</Figure>

## Prerequisites

You need:

- A Quake AI account with S3 credentials: complete the [object storage tutorial](/docs/quickstart/object-storage-upload) if you have not created credentials yet
- A Linux or macOS machine (the machine you want to back up)
- A directory with files worth backing up: your home projects folder, a code repository, or configuration files all work well

## Why off-site backups

Every backup strategy starts with the same question: what happens if your primary storage disappears? A disk fails, a laptop is stolen, a cloud provider has an outage, or you accidentally run `rm -rf` in the wrong directory. Local backups protect against some of these scenarios, but not all. If the backup lives on the same machine (or same provider) as the original, a single failure can take both copies.

The 3-2-1 rule is the industry standard: keep **three** copies of your data, on **two** different storage media, with **one** copy off-site. Quake AI object storage serves as the off-site copy. Your data is stored redundantly across Quake AI's infrastructure, separate from whatever machine or provider holds the original.

## Step 1: Create a backup bucket

You need a dedicated container (bucket) on Quake AI to hold your backups. If you completed the object storage tutorial, you already know how this works. Create a separate bucket for backups to keep them isolated from other data.

```bash
aws s3 mb s3://my-backups --profile rumble
```

If you have not configured the `rumble` CLI profile yet, follow [Step 2 of the object storage tutorial](/docs/quickstart/object-storage-upload#step-2--configure-the-aws-cli) first.

Verify the bucket exists:

```bash
aws s3 ls --profile rumble
```

You should see `my-backups` in the list.

## Step 2: install rclone

rclone is a command-line tool that syncs files between your local machine and cloud storage providers. It supports over 70 backends, including S3-compatible services like Quake AI. Use rclone instead of the AWS CLI for backups because it handles incremental transfers, bandwidth limits, and retry logic without extra configuration.

**macOS:**

```bash
brew install rclone
```

**Linux:**

```bash
curl -fsSL https://rclone.org/install.sh | sudo bash
```

Verify the installation:

```bash
rclone version
```

You should see version 1.65 or later.

## Step 3: Configure the Quake AI remote

rclone uses named remotes to store connection details. Create a remote called `rumble` that points to your Quake AI object storage.

Edit the rclone configuration file:

```bash
mkdir -p ~/.config/rclone
nano ~/.config/rclone/rclone.conf
```

Add the following block, replacing the placeholder values with your S3 credentials and region endpoint:

```ini
[quakeai]
type = s3
provider = Ceph
access_key_id = YOUR_ACCESS_KEY
secret_access_key = YOUR_SECRET_KEY
endpoint = object.us-east-1.rumble.cloud
acl = private
```



Use the endpoint that matches your project's region:

| Region | Endpoint |
|--------|----------|
| US East 1 | `object.us-east-1.rumble.cloud` |
| US East 2 | `object.us-east-2.rumble.cloud` |
| US West 1 | `object.us-west-1.rumble.cloud` |



Save the file. The block you pasted contains your plaintext Quake AI S3 secret key, and a default Linux file mode leaves the config world-readable to other local accounts. Lock the file down:

```bash
chmod 600 ~/.config/rclone/rclone.conf
```



The rclone config file stores your plaintext Quake AI S3 secret key. Set its mode to `0600` so other local users cannot read it:

```bash
chmod 600 ~/.config/rclone/rclone.conf
```

On a multi-user host or any shared machine, this step is mandatory. For production deployments, load credentials from environment variables or a secret manager and remove the long-lived secret from disk entirely.



Verify the connection:

```bash
rclone lsd quakeai:
```

This lists your buckets. You should see `my-backups` in the output. If you get an authentication error, double-check that the access key and secret key match what you created in the Quake AI console.

## Step 4: Run your first backup

Pick a directory to back up. This tutorial uses `~/projects`; replace it with whatever directory holds files you care about.

```bash
rclone copy ~/projects quakeai:my-backups/projects \
  --transfers 8 \
  --progress
```

What each flag does:

- `copy` uploads files from source to destination without deleting anything at the destination. This is safer than `sync` for backups because a local deletion does not propagate to your backup.
- `--transfers 8` runs 8 parallel uploads for speed.
- `--progress` shows real-time transfer statistics.

When the command completes, verify the files arrived:

```bash
rclone ls quakeai:my-backups/projects | head -20
```

You should see your project files listed with their sizes. Compare the count:

```bash
echo "Local files: $(find ~/projects -type f | wc -l)"
echo "Remote files: $(rclone ls quakeai:my-backups/projects | wc -l)"
```

If the counts match, your first backup is complete.



Add `--exclude-from` to skip files that do not belong in backups:

```bash
cat > ~/.config/rclone/backup-exclude.txt << 'EOF'
node_modules/**
.git/**
__pycache__/**
*.pyc
.DS_Store
.env
EOF
```

Then add `--exclude-from ~/.config/rclone/backup-exclude.txt` to your rclone command. Excluding `node_modules` and `.git` alone can reduce backup size by 80% or more for typical development projects.



## Step 5: Add encryption with restic

rclone copies files in plain text. If your backups contain credentials, configuration files, or anything sensitive, encrypt them before they leave your machine. restic is a backup tool that encrypts and deduplicates data before uploading, using rclone as the transport layer.

Install restic:

**macOS:**

```bash
brew install restic
```

**Linux:**

```bash
sudo apt install -y restic
```

Initialize a restic repository on your Quake AI bucket. restic asks you to set a password: this password encrypts all backup data. Store it somewhere safe. If you lose it, the backups are unrecoverable.

```bash
restic -r rclone:quakeai:my-backups/restic-repo init
```

restic creates an encrypted repository structure inside the `restic-repo` prefix in your bucket.

Run an encrypted backup:

```bash
restic -r rclone:quakeai:my-backups/restic-repo backup ~/projects \
  --exclude-file ~/.config/rclone/backup-exclude.txt
```

restic reports how many files it processed, the new data uploaded, and the total repository size. The first backup uploads everything; subsequent backups upload only changed blocks, which is typically much faster.

List your backup snapshots:

```bash
restic -r rclone:quakeai:my-backups/restic-repo snapshots
```

Each snapshot is a point-in-time copy of your data. You can restore to any snapshot individually.

## Step 6: Schedule automatic backups

A backup you have to remember to run is a backup you will forget to run. Use cron to schedule daily backups at 2:00 AM.

Create a backup script:

```bash
cat > ~/backup-to-rumble.sh << 'SCRIPT'
#!/bin/bash
set -euo pipefail

LOG_FILE="$HOME/.local/log/rumble-backup.log"
mkdir -p "$(dirname "$LOG_FILE")"

echo "=== Backup started: $(date -Iseconds) ===" >> "$LOG_FILE"

restic -r rclone:quakeai:my-backups/restic-repo backup ~/projects \
  --exclude-file "$HOME/.config/rclone/backup-exclude.txt" \
  >> "$LOG_FILE" 2>&1

restic -r rclone:quakeai:my-backups/restic-repo forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune \
  >> "$LOG_FILE" 2>&1

echo "=== Backup finished: $(date -Iseconds) ===" >> "$LOG_FILE"
SCRIPT

chmod +x ~/backup-to-rumble.sh
```

The script does two things: runs a backup, then prunes old snapshots using a retention policy that keeps the last 7 daily, 4 weekly, and 6 monthly snapshots. This prevents unbounded storage growth while maintaining a useful history.

Set the restic password as an environment variable so cron can access it without a prompt. Create a password file:

```bash
echo "YOUR_RESTIC_PASSWORD" > ~/.config/restic/password
chmod 600 ~/.config/restic/password
```

Update the script to use the password file by adding this line after `set -euo pipefail`:

```bash
export RESTIC_PASSWORD_FILE="$HOME/.config/restic/password"
```

Add the cron job:

```bash
crontab -e
```

Add this line:

```text
0 2 * * * /bin/bash $HOME/backup-to-rumble.sh
```

This runs the backup script every day at 2:00 AM. Check the log file the next morning to confirm it ran:

```bash
tail -20 ~/.local/log/rumble-backup.log
```

## Step 7: Test a restore

A backup you have never restored is a backup you cannot trust. Test the restore process now, while everything is fresh, rather than discovering problems during an emergency.

Create a temporary directory and restore the latest snapshot:

```bash
mkdir -p /tmp/restore-test

restic -r rclone:quakeai:my-backups/restic-repo restore latest \
  --target /tmp/restore-test
```

restic prints a summary when it finishes:

```text
restoring snapshot 1a2b3c4d of [/home/alex/projects] at 2026-06-04 02:00:14 UTC by alex@workstation to /tmp/restore-test
Summary: Restored 42 files/dirs (12.480 MiB) in 0:03
```

restic restores files preserving their original absolute path under the `--target` directory. The summary line shows that path in brackets. Because you backed up `~/projects`, the restored copy lands at `/tmp/restore-test$HOME/projects` (for example `/tmp/restore-test/home/alex/projects`), not `/tmp/restore-test/projects`.

Verify the restored files match the originals by pointing `diff` at that path:

```bash
diff -rq ~/projects "/tmp/restore-test$HOME/projects"
```

If `diff` prints nothing, the restored files are identical to the originals and your backup-and-restore cycle works end to end. If it reports differences, check whether they come from files that changed between the backup and the restore (expected) or from files that were excluded or corrupted (investigate).

Clean up the test:

```bash
rm -rf /tmp/restore-test
```

## What you learned

In this walkthrough, you:

- **Created a dedicated backup bucket** on Quake AI object storage
- **Installed and configured rclone** as the transport layer to Quake AI's S3-compatible endpoint
- **Ran a plain-text backup** with rclone copy and verified the file counts match
- **Added encryption and deduplication** with restic, so sensitive files are protected before they leave your machine
- **Scheduled daily backups** with cron and a retention policy that balances history against storage cost
- **Tested a full restore** to prove the backups are recoverable data, not inert bytes in a bucket

Your backup pipeline is now running. The restic repository grows incrementally: only changed blocks are uploaded each day, so storage costs stay proportional to your actual data changes, not your total data size.

## Next steps

- [How to back up and restore a Quake AI VM](/docs/compute/how-to/backup-and-restore): snapshot-based VM recovery on the platform
- [How to schedule volume snapshots and restore data](/docs/block/how-to/schedule-snapshots-and-restore): Cinder snapshot schedules for attached volumes
- [Migrate from AWS S3 to Quake AI](/resources/migration/migrate-from-s3): move your production S3 data to Quake AI
- [Back up to Quake AI](/docs/object/migration/backup-to-quake-ai): the how-to reference with additional patterns (database backups, systemd timers, monitoring)
- [Object storage pricing](/docs/account/billing/pricing): understand the cost of your backup storage
- [S3 feature compatibility](/docs/object/migration/plan-your-migration): what S3 features Quake AI supports and what it does not

## Clean up

If you are done experimenting and want to remove the backup infrastructure:

Remove the cron job:

```bash
crontab -e
```

Delete the line containing `backup-to-rumble.sh`.

Delete the restic repository and backup bucket:

```bash
rclone purge quakeai:my-backups
```

Remove local configuration:

```bash
rm ~/backup-to-rumble.sh
rm ~/.config/restic/password
```

The bucket and all its contents are permanently deleted. No charges accrue after deletion.
