Featured image of post Restic 自动化备份到 S3 兼容存储:VPS 数据保险箱完整指南

Restic 自动化备份到 S3 兼容存储:VPS 数据保险箱完整指南

使用 Restic + MinIO/S3 构建自动化的 VPS 备份系统,实现加密存储、去重压缩、定时任务与一键恢复。

引言

在自托管和 VPS 运维中,备份是最后一道防线。rclone 适合文件同步,但如果你需要版本化备份、加密存储、增量去重——Restic 是目前最优雅的开源解决方案之一。

本文将带你从零搭建一套完整的 Restic 备份系统,将数据加密备份到 S3 兼容存储(MinIO、AWS S3、Cloudflare R2 均可),并配合 crontab 实现全自动无人值守。


一、为什么选择 Restic?

特性Resticrclone copyrsync
增量备份✅ 块级别去重❌ 全量❌ 文件级别
端到端加密✅ 内置 AES-256❌ 需额外配置
快照管理✅ 自动版本控制
S3/R2 原生支持
跨平台Linux/macOS/Windows全平台Linux/macOS
恢复粒度文件/目录/整卷文件/目录文件/目录

核心优势:Restic 在仓库级别做块去重,同一个 1TB 的磁盘镜像,第二次备份可能只上传几 MB 的新增数据。配合加密,你的备份即使落在公共云上也绝对安全。


二、架构总览

┌──────────────────────────────────────────────────┐
│                   VPS (源服务器)                    │
│                                                  │
│  ┌────────┐   ┌──────────┐   ┌───────────────┐   │
│  │ /etc    │   │ /home    │   │ 数据库 dumps  │   │
│  │ 配置文件 │   │ 用户数据  │   │  (mysqldump)  │   │
│  └────┬────┘   └────┬─────┘   └───────┬───────┘   │
│       │             │                 │            │
│       └──────────┬──┴─────────────────┘            │
│                  ▼                                  │
│         ┌───────────────┐                          │
│         │   Restic CLI   │  加密 + 去重 + 快照      │
│         └───────┬───────┘                          │
│                 │ HTTPS                            │
└─────────────────┼──────────────────────────────────┘
                  │
          ┌───────▼────────┐
          │  S3 兼容存储     │
          │  (MinIO / R2)  │
          │  加密对象仓库    │
          └────────────────┘

三、环境准备

3.1 安装 Restic

# Ubuntu/Debian
wget https://github.com/restic/restic/releases/latest/download/restic_0.17.0_$(dpkg --print-architecture).deb
sudo dpkg -i restic_0.17.0_$(dpkg --print-architecture).deb

# 或从源码编译
git clone https://github.com/restic/restic.git
cd restic && go build && sudo cp restic /usr/local/bin/

# 验证安装
restic version
# restic 0.17.0 compiled at 2024-12-18 19:29:04 UTC using go1.23.4

3.2 部署 S3 兼容存储(MinIO)

如果你的 VPS 有足够资源,可以直接在本机跑 MinIO:

# 单二进制部署 MinIO
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/

# 创建数据目录
sudo mkdir -p /data/minio
sudo useradd -r -s /bin/false minio
sudo chown minio:minio /data/minio

# 创建 systemd 服务
sudo tee /etc/systemd/system/minio.service > /dev/null <<'EOF'
[Unit]
Description=MinIO Object Storage
After=network-online.target

[Service]
User=minio
Group=minio
ExecStart=/usr/local/bin/minio server /data/minio \
  --console-address ":9001" \
  --address ":9000"
Restart=always
Environment="MINIO_ROOT_USER=admin"
Environment="MINIO_ROOT_PASSWORD=your-strong-password-here"

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now minio

访问 http://<your-vps-ip>:9001 创建 bucket,比如 restic-backups

替代方案:如果不想跑 MinIO,直接用 Cloudflare R2(零出口流量费)或 AWS S3。

3.3 配置 S3 环境变量

# 添加到 ~/.bashrc 或 /etc/environment
export S3_ENDPOINT="http://127.0.0.1:9000"    # MinIO 地址
export S3_ACCESS_KEY="admin"
export S3_SECRET_KEY="your-strong-password-here"
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/restic-backups"
export RESTIC_PASSWORD="your-encryption-passphrase"

# 立即生效
source ~/.bashrc

如果是 Cloudflare R2:

export S3_ENDPOINT="https://s3.us-east-1.r2.cloudflarestorage.com"
export S3_ACCESS_KEY="<r2-access-key>"
export S3_SECRET_KEY="<r2-secret-key>"
export RESTIC_REPOSITORY="s3:s3.us-east-1.r2.cloudflarestorage.com/restic-backups"

四、初始化仓库与首次备份

4.1 初始化仓库

restic init
# created restic repository <repo-id> at ...
# 密码保护已启用

4.2 备份关键目录

# 备份多个路径
restic backup /etc /home /var/www --tag vps-config --tag production

# 查看快照
restic snapshots
# ID        Date                  Host    Tags       Paths
# a1b2c3d4  2026-07-25 03:00:12   vps01   vps-config  /etc /home /var/www
# 4 objects stored, has been excluded from listing
# 5 objects stored, new size: 2.345 GiB

# 查看仓库统计
restic stats
# total files: 12847
# total bytes: 2.345 GiB
# unique data: 892 MiB  ← 去重后实际存储量
# compressed:  1.123 GiB

4.3 数据库专项备份

Restic 备份文件级数据,数据库建议先 dump 再备份:

#!/bin/bash
# /usr/local/bin/db-backup.sh
set -euo pipefail

BACKUP_DIR="/tmp/restic-db-dump"
mkdir -p "$BACKUP_DIR"

# MySQL/MariaDB
for db in $(mysql -e 'SHOW DATABASES;' -N | grep -v '^Information\|^performance'); do
    mysqldump --single-transaction --routines --triggers "$db" \
        > "$BACKUP_DIR/${db}_$(date +%Y%m%d_%H%M%S).sql"
done

# PostgreSQL
pg_dumpall > "$BACKUP_DIR/all_pg_$(date +%Y%m%d_%H%M%S).sql"

# 用 Restic 备份 dump 文件
restic backup "$BACKUP_DIR" --tag database-dumps
rm -rf "$BACKUP_DIR"
echo "$(date): Database backups completed successfully" >> /var/log/db-backup.log
sudo chmod +x /usr/local/bin/db-backup.sh

五、自动化定时备份

5.1 Crontab 配置

# 创建专用备份脚本
sudo tee /usr/local/bin/restic-auto-backup.sh > /dev/null <<'SCRIPT'
#!/bin/bash
set -euo pipefail

LOG="/var/log/restic-backup.log"
LOCKFILE="/tmp/restic-backup.lock"

# 防止并发执行
exec 200>"$LOCKFILE"
flock -n 200 || { echo "$(date): Another backup is running, exiting." >> "$LOG"; exit 0; }

echo "=== Backup started at $(date) ===" >> "$LOG"

# 前置:数据库 dump
/usr/local/bin/db-backup.sh >> "$LOG" 2>&1

# 执行 Restic 备份
restic backup \
    /etc \
    /home \
    /var/www \
    /tmp/restic-db-dump \
    --tag auto-backup \
    --tag "$(date +%Y-%m)" \
    >> "$LOG" 2>&1

# 清理旧快照:保留最近 7 天每日、4 周每周、12 月每月
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune >> "$LOG" 2>&1

echo "=== Backup completed at $(date) ===" >> "$LOG"
rm -rf /tmp/restic-db-dump

# 释放锁
flock -u 200
SCRIPT

sudo chmod +x /usr/local/bin/restic-auto-backup.sh
# 编辑 crontab
crontab -e

# 每天凌晨 3 点备份,邮件通知结果
0 3 * * * /usr/local/bin/restic-auto-backup.sh

5.2 监控告警

# 检查备份是否成功
restic check --read-data-store >> /var/log/restic-health.log 2>&1

# 设置健康检查 cron
0 6 * * * restic snapshots --last 1 | tail -1 >> /var/log/restic-status.log 2>&1

六、恢复操作

6.1 列出所有快照

restic snapshots
restic snapshots --tag auto-backup

6.2 恢复单个文件

# 恢复到指定目录
restic restore latest --target /tmp/recovered/

# 恢复特定路径
restic restore a1b2c3d4 --include "/etc/nginx/nginx.conf" --target /tmp/

# 恢复特定标签的快照
restic restore --tag production --target /tmp/prod-recovery/

6.3 恢复整个系统

# 挂载为 FUSE(实时浏览)
sudo apt install restic-fuse  # 部分发行版提供
restic mount /mnt/restic &
ls /mnt/restic/

# 从 ISO 启动进行整机恢复
# 挂载备份目标盘,然后:
restic restore latest --target /mnt/recovery/

七、最佳实践与优化

7.1 排除不需要备份的内容

restic backup /home --exclude '*.cache' --exclude '.local/share/Trash' --exclude 'node_modules'

7.2 仓库健康检查

# 每周运行一次
restic check --quiet
# 输出无内容 = 正常

# 强制重建索引
restic rebuild-index

7.3 多仓库策略

生产环境 → R2 (冷备, 每月一次)
开发环境 → MinIO (热备, 每天)
个人数据 → 本地 NAS (本地)

7.4 密码管理

# 不要把密码写在脚本里!使用密钥管理器
export RESTIC_PASSWORD_FILE=/run/secrets/restic-password
# 或
export RESTIC_PASSWORD_KEYRING=1  # 使用 libsecret/keyring

八、成本估算

方案存储成本月费参考
MinIO (本地)硬件成本¥0 (已有硬盘)
Cloudflare R2免费 10GB, 之后 $0.015/GB~¥15/月 (1TB)
AWS S3 Standard$0.023/GB~¥25/月 (1TB)
Backblaze B2$0.005/GB~¥7/月 (1TB)

Restic 的去重特性意味着:100GB 的每日备份,如果每天只变更 2%,一个月只需额外存储约 6GB。


总结

Restic + S3 的组合为 VPS 运维提供了:

  • 加密安全:AES-256 端到端加密,云端也无法读取你的数据
  • 极致去重:块级别 dedup,节省 70-90% 存储空间
  • 版本历史:无限快照,随时回滚到任意时间点
  • 自动化友好:一行命令触发,完美配合 crontab

📦 下一步:为你的 VPS 配置 Restic 自动备份,然后务必做一次恢复测试——没有经过恢复验证的备份等于没有备份。

📺 看视频版教程 → DuckDB Lab YouTube

Subscribe for more DuckDB & AI automation tutorials