# Automated Instance Backup to Zata S3 Using Restic

Back up your NeevCloud Linux Instance to [Zata](https://zata.ai) S3 object storage with encryption, deduplication, and automated scheduling using Restic, A fast, secure, open-source backup tool.

### Overview

| Feature             | Details                                     |
| ------------------- | ------------------------------------------- |
| Backup tool         | [Restic](https://restic.net/) (open source) |
| Storage backend     | [Zata S3](https://zata.ai) (Ceph RGW)       |
| Encryption          | AES-256 (client-side, at rest)              |
| In-transit security | TLS 1.3                                     |
| Backup type         | File-level (incremental, deduplicated)      |
| Supported distros   | Ubuntu/Debian, RHEL/CentOS, AlmaLinux       |
| Scheduling          | systemd timer                               |

### Prerequisites

* A running NeevCloud Linux Instance.
* A Zata S3 bucket (create one from the [Zata Console](https://my.zata.ai/))
* Zata S3 credentials: Access Key and Secret Key
* Root access on the cloud Instance

### Install Restic

#### Ubuntu / Debian

```bash
sudo apt update && sudo apt install -y restic
restic version
```

#### RHEL / CentOS / AlmaLinux

```bash
sudo yum install -y epel-release
sudo yum install -y restic
restic version
```

### Configure Credentials

Create a secure environment file:

```bash
sudo mkdir -p /etc/restic

sudo tee /etc/restic/env > /dev/null <<'EOF'
AWS_ACCESS_KEY_ID=<your-zata-access-key>
AWS_SECRET_ACCESS_KEY=<your-zata-secret-key>
RESTIC_REPOSITORY=s3:https://idr01.zata.ai/<your-bucket-name>
RESTIC_PASSWORD=<choose-a-strong-encryption-passphrase>
EOF

sudo chmod 600 /etc/restic/env
```

> **Important:** Store your `RESTIC_PASSWORD` securely. Without it, your backups cannot be restored.

### Define Backup Paths

Create include and exclude lists:

```bash
sudo tee /etc/restic/includes.txt > /dev/null <<'EOF'
/etc
/opt
/var/www
/home
EOF

sudo tee /etc/restic/excludes.txt > /dev/null <<'EOF'
*.tmp
*.cache
/var/www/*/cache
EOF
```

Modify these paths based on your application and data layout.

### Initialize the Backup Repository

Run this once to create the restic repository in your [Zata](https://zata.ai) S3 bucket:

```bash
source /etc/restic/env
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY RESTIC_REPOSITORY RESTIC_PASSWORD
restic init
```

Expected output:

```
created restic repository xxxxxxxx at s3:https://idr01.zata.ai/<your-bucket-name>
```

### Run Your First Backup

```bash
source /etc/restic/env
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY RESTIC_REPOSITORY RESTIC_PASSWORD

restic backup \
    --files-from /etc/restic/includes.txt \
    --exclude-file /etc/restic/excludes.txt \
    --tag manual \
    --hostname "$(hostname)"
```

Verify the snapshot:

```bash
restic snapshots
```

### Automate with Scheduled Backups

#### Create the backup wrapper script

```bash
sudo tee /usr/local/bin/restic-backup.sh > /dev/null <<'SCRIPT'
#!/bin/bash
set -euo pipefail

source /etc/restic/env
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY RESTIC_REPOSITORY RESTIC_PASSWORD

LOG="/var/log/restic-backup.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG"; }

log "===== BACKUP START ====="

restic backup \
    --files-from /etc/restic/includes.txt \
    --exclude-file /etc/restic/excludes.txt \
    --tag auto \
    --hostname "$(hostname)" \
    >> "$LOG" 2>&1 && log "BACKUP: SUCCESS" || log "BACKUP: FAILED"

restic forget \
    --keep-daily 30 \
    --keep-weekly 4 \
    --keep-monthly 6 \
    --prune \
    >> "$LOG" 2>&1 && log "PRUNE: SUCCESS" || log "PRUNE: FAILED"

log "===== BACKUP END ====="
SCRIPT

sudo chmod 750 /usr/local/bin/restic-backup.sh
```

#### Create the systemd service and timer

```bash
sudo tee /etc/systemd/system/restic-backup.service > /dev/null <<'EOF'
[Unit]
Description=Restic Backup to Zata S3
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh
Nice=10
EOF

sudo tee /etc/systemd/system/restic-backup.timer > /dev/null <<'EOF'
[Unit]
Description=Restic Backup Daily Schedule

[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=900
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
```

#### Verify the timer

```bash
systemctl list-timers restic-backup.timer
```

#### Test a manual run

```bash
sudo /usr/local/bin/restic-backup.sh && cat /var/log/restic-backup.log
```

### Restore from Backup

#### List available snapshots

```bash
restic snapshots
```

#### Restore the latest snapshot

```bash
restic restore latest --target /opt/restored-data
```

#### Restore a specific snapshot

```bash
restic restore <snapshot-id> --target /opt/restored-data
```

#### Restore specific files only

```bash
restic restore latest --target /opt/restored-data --include "/etc/nginx"
```

### Retention Policy

The automated script applies the following default retention:

| Rule              | Value |
| ----------------- | ----- |
| Daily snapshots   | 30    |
| Weekly snapshots  | 4     |
| Monthly snapshots | 6     |

Modify these values in `/usr/local/bin/restic-backup.sh` to match your requirements.

### Useful Commands

| Command                                   | Description                         |
| ----------------------------------------- | ----------------------------------- |
| `restic snapshots`                        | List all backup snapshots           |
| `restic ls latest`                        | Browse files in the latest snapshot |
| `restic stats`                            | Show repository size and stats      |
| `restic check`                            | Verify repository integrity         |
| `restic diff <id1> <id2>`                 | Compare two snapshots               |
| `restic forget --dry-run --keep-daily 30` | Preview what would be pruned        |

### Check Backup Logs

```bash
tail -50 /var/log/restic-backup.log
```

### Troubleshooting

**`Fatal: unable to open config file`** Repository not initialized. Run `restic init` first.

**`Fatal: wrong password or no key found`** Verify `RESTIC_PASSWORD` matches the one used during `restic init`.

**`connection refused` or `TLS handshake error`** Check network connectivity to `idr01.zata.ai`. Ensure port 443 is open in your security group.

**Slow backup speeds** Ensure the VM has sufficient network bandwidth. Restic deduplicates — subsequent backups will be significantly faster than the initial one.

### Support

For assistance with [Zata S3](https://zata.ai) credentials, bucket configuration, or backup setup, contact [NeevCloud support](/neevcloud-products/support/raising-managing-tickets.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.neevcloud.com/neevcloud-guide/neevcloud-remote-backup-and-dr/automated-instance-backup-to-zata-s3-using-restic.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
