一键备份 · 数据库安全导出 · 双网盘上传 · GPG 加密 · Telegram 远程管理
自动备份 VPS 上所有运行中的 Docker 容器(含 docker-compose 项目),内建数据库智能检测与安全导出,支持上传到 OneDrive + Google Drive 双网盘,并可通过 Telegram Bot 进行远程管理。
⚠️ 核心规则:仅备份 Running 状态的容器
脚本通过docker ps扫描当前处于 Running 状态的容器。已停止 (Exited) 或暂停 (Paused) 的容器不会被备份。如需备份某个已停止的容器,请先docker start <容器>启动它。
🗄️ 数据库智能导出
自动检测 MySQL / MariaDB / PostgreSQL / MongoDB 容器,使用mysqldump/pg_dumpall/mongodump执行一致性安全导出。导出失败时自动降级为卷打包,不中断整体备份流程。
| 能力 | 说明 |
|---|---|
| 🐳 全容器备份 | 所有 Running 容器的 inspect JSON + 卷数据 + 运行参数 |
| 🧩 Compose 支持 | 自动识别 docker-compose 项目,打包完整的 docker-compose.yml + 目录 |
| 🗄️ 数据库安全导出 | MySQL / MariaDB / PostgreSQL / MongoDB 专用导出,保证数据一致性 |
| � GPG 加密 | 可选 AES256 对称加密,备份文件上传前自动加密 |
| ☁️ 双网盘上传 | OneDrive + Google Drive 自动上传,远程保留策略 |
| 🤖 Telegram Bot | 远程查看状态、手动触发备份,实时回显执行进度 |
| 🔄 完整还原 | 一键恢复所有容器(含 compose 项目 + 数据库 dump + 卷数据) |
| 🌐 多网络支持 | host / bridge / 自定义 bridge / compose 网络全兼容 |
| ⚙️ 参数全保留 | 还原时完整保留 --privileged / --shm-size / --dns / --security-opt / --cap-drop / --init / HEALTHCHECK / labels / workdir 等 |
| 📄 文件 | 🎯 用途 |
|---|---|
bf.sh |
主备份脚本,支持 cron 定时或手动执行 |
db_dump.sh |
数据库自动检测 + 专用安全导出模块 |
restore.sh |
一键恢复脚本(容器 + Compose + 数据库 dump) |
tg_bot.py |
Telegram Bot,远程查看状态 / 触发备份 |
tg_bot.service |
Bot 的 systemd 服务文件 |
install_bot.sh |
Bot 一键部署脚本 |
| 项目 | 要求 |
|---|---|
| 🖥️ 操作系统 | Ubuntu 20.04+ / Debian 11+ / CentOS 7+ |
| 🐳 Docker | 已安装并正常运行(docker ps 可执行) |
| 🔑 权限 | root |
| 🔧 Git | 已安装 |
| ☁️ 网盘 (可选) | rclone 已配置 onedrive 和 gdrive remote |
cd /root
git clone https://github.com/Agff45/vps_docker-bf.git bf
cd /root/bf
chmod +x *.shapt update && apt install -y jq tar gzip curl🔐 可选:安装 GPG 加密支持
apt install -y gnupg
🚨 重要:rclone remote 名必须固定为
onedrive和gdrive,脚本通过名称识别网盘。
📂 点击展开 rclone 配置步骤
# 安装 rclone
curl https://rclone.org/install.sh | bash
# 交互式配置(remote 名必须填写 onedrive 和 gdrive)
rclone config配置过程中按提示操作:
- 输入
n新建 remote - 名称输入
onedrive - 类型选择
onedrive(OneDrive)或drive(Google Drive) - 按提示完成 OAuth 授权
# 验证配置是否成功
rclone lsd onedrive:
rclone lsd gdrive:💡 不想用网盘? 跳过此步骤即可。备份会保存在本地
VPS_Backups/目录,网盘上传步骤会显示失败,不影响本地备份。
两个配置项的区别:
TG_BOT_TOKEN/BOT_TOKEN— Telegram 机器人的 Token,由 @BotFather 发放,格式123456:ABC-DEF1234gh...TG_CHAT_ID/ALLOWED_CHAT_ID— 你个人账户的数字 ID,由 @userinfobot 查询,格式123456789两者缺一不可:Token 让脚本操控机器人,Chat ID 确保只有你能发命令。
nano /root/bf/bf.sh找到配置区域,修改以下三行:
TG_BOT_TOKEN="你的BotToken"
TG_CHAT_ID="你的ChatID"
TG_ENABLED=true # 不需要通知就改为 falsenano /root/bf/tg_bot.py修改第 16-17 行:
BOT_TOKEN = "你的BotToken"
ALLOWED_CHAT_ID = 你的ChatID
⚠️ 如果不想用 Telegram 通知和 Bot,在bf.sh中把TG_ENABLED设为false,并且不要执行步骤 9。
bf.sh 默认已启用数据库自动检测。如需关闭:
# bf.sh 配置区域
DB_DUMP_ENABLED=false # 设为 false 关闭数据库专用导出| 数据库 | 检测方式 | 导出命令 | 导出文件 |
|---|---|---|---|
| MySQL | 镜像名含 mysql |
mysqldump --all-databases --single-transaction --routines --triggers --events |
容器名_mysqldump_all.sql.gz |
| MariaDB | 镜像名含 mariadb |
mysqldump --all-databases --single-transaction |
容器名_mysqldump_all.sql.gz |
| PostgreSQL | 镜像名含 postgres / postgis |
pg_dumpall |
容器名_pgdumpall.sql.gz |
| MongoDB | 镜像名含 mongo |
mongodump --archive |
容器名_mongodump.archive.gz |
| 数据库 | 读取的环境变量 |
|---|---|
| MySQL | MYSQL_ROOT_PASSWORD |
| MariaDB | MARIADB_ROOT_PASSWORD |
| PostgreSQL | POSTGRES_USER + POSTGRES_PASSWORD |
| MongoDB | MONGO_INITDB_ROOT_USERNAME + MONGO_INITDB_ROOT_PASSWORD |
如果专用导出失败(容器内缺少客户端工具 / 密码错误 / 无认证 MongoDB 等),脚本自动回退为 卷数据 tar 打包,不中断备份。
启用后备份文件在上传前使用 AES256 对称加密,生成 .tar.gz.gpg 文件。
安装 GPG:
apt install -y gnupg配置 bf.sh:
ENCRYPT_ENABLED=true # 开启加密
ENCRYPT_PASSPHRASE="你的加密密码" # 设置密码(⚠️ 必须设置,空密码会跳过加密)恢复加密备份:
./restore.sh backup.tar.gz.gpg 你的加密密码/root/bf/bf.sh✅ 正常输出流程:
依赖检查→容器扫描→数据库检测→数据导出→打包完成→网盘上传结果
预期输出示例:
[Sun May 3 01:07:37 CST 2026] 🚀 开始 Docker 容器备份...
🔍 检查依赖...
✅ 所有依赖就绪
🐳 正在扫描 Docker 容器...
📋 发现 23 个运行中的容器
🕵️ ==== 数据库自动检测 ====
🔍 检测到数据库: [mysql_main] 类型=mysql
🔍 检测到数据库: [postgres_main] 类型=postgres
📊 共检测到 2 个数据库容器
🩺 对数据库容器 [mysql_main] (mysql) 执行专用导出...
✅ [mysql_main] 导出成功: mysql_main_mysqldump_all.sql.gz (876K)
🩺 对数据库容器 [postgres_main] (postgres) 执行专用导出...
✅ [postgres_main] 导出成功: postgres_main_pgdumpall.sql.gz (20K)
✅ 数据库专用导出完成: 2/2 个成功
📦 打包备份目录...
✅ 打包完成: docker_backup_20260503_010737.tar.gz (2.5M)
🎉 所有任务完成.
(crontab -l 2>/dev/null; echo "0 3 * * * /root/bf/bf.sh >> /var/log/docker_backup.log 2>&1") | crontab -📅 默认每天 凌晨 3 点 自动执行,可自行修改 cron 表达式。
📂 Crontab 常用时间参考
| 时间 | 表达式 |
|---|---|
| 每天凌晨 2 点 | 0 2 * * * |
| 每天凌晨 3 点 | 0 3 * * * |
| 每 6 小时 | 0 */6 * * * |
| 每周日凌晨 3 点 | 0 3 * * 0 |
/root/bf/install_bot.sh脚本自动完成:
- 创建 Python 虚拟环境
- 安装
python-telegram-bot依赖 - 配置 systemd 服务并设为开机自启
# Bot 管理命令
systemctl status tg_bot # 查看运行状态
systemctl restart tg_bot # 重启 Bot
systemctl stop tg_bot # 停止 Bot
journalctl -u tg_bot -f # 实时查看日志| ✅ 检查项 | 📟 命令 |
|---|---|
| 手动备份 | /root/bf/bf.sh |
| 查看备份文件 | ls -lh /root/bf/VPS_Backups/ |
| Bot 状态 | systemctl status tg_bot |
| 定时任务 | crontab -l |
cd /root/bf
# 恢复未加密备份
./restore.sh VPS_Backups/docker_backup_YYYYMMDD_HHMMSS.tar.gz
# 恢复加密备份
./restore.sh VPS_Backups/docker_backup_YYYYMMDD_HHMMSS.tar.gz.gpg 你的加密密码┌─────────────────────────────────────────────────┐
│ 1️⃣ 还原 docker-compose 项目 │
│ · 解压 compose 项目目录 │
│ · docker compose up -d 启动 │
│ · 已运行的项目自动跳过 │
├─────────────────────────────────────────────────┤
│ 2️⃣ 还原普通 Docker 容器 │
│ · 恢复卷数据 (tar) │
│ · 还原 SSH 端口映射 / 环境变量 / 网络 / 重启策略 │
│ · 还原 tmpfs / read_only / cap / init / DNS │
│ · 还原 HEALTHCHECK / labels / workdir │
│ · 缺失的自定义网络自动创建 │
├─────────────────────────────────────────────────┤
│ 3️⃣ 还原 /home/docker 下的文件 │
├─────────────────────────────────────────────────┤
│ 4️⃣ 还原数据库 dump │
│ · 等待数据库就绪(健康检查轮询,最多 60s) │
│ · zcat dump.gz → mysql / psql / mongorestore │
└─────────────────────────────────────────────────┘
| 参数 | 来源 | 备注 |
|---|---|---|
--name |
容器名 | 原始名称 |
-p |
HostConfig.PortBindings |
TCP/UDP 协议完整保留;host 网络自动跳过 |
-e |
Config.Env |
含特殊字符(!@#$% / 引号 / 换行) |
-v |
Mounts |
bind mount + volume 均支持 |
--network |
HostConfig.NetworkMode |
缺失网络自动 docker network create |
--restart |
HostConfig.RestartPolicy |
含 on-failure:N 重试次数 |
--tmpfs |
HostConfig.Tmpfs |
保留 size 参数 |
--read-only |
HostConfig.ReadonlyRootfs |
|
--cap-drop / --cap-add |
HostConfig.CapDrop / CapAdd |
|
--init |
HostConfig.Init |
|
--privileged |
HostConfig.Privileged |
|
--shm-size |
HostConfig.ShmSize |
字节精确还原 |
--dns |
HostConfig.Dns |
支持多个 |
--security-opt |
HostConfig.SecurityOpt |
支持多个 |
--health-cmd / --health-interval / --health-timeout / --health-retries |
Config.Healthcheck |
纳秒自动转秒 |
--label |
Config.Labels |
自动跳过 com.docker.* 内部标签 |
--workdir |
Config.WorkingDir |
|
IMAGE [CMD...] |
Config.Image + Config.Cmd |
保留原始启动命令 |
🛡️ 已运行的容器及 Compose 项目会自动跳过,不会重复创建。
# ================= 配置区域 =================
# --- 本地设置 ---
BACKUP_DIR="/root/bf/VPS_Backups" # 本地备份存放目录
LOCAL_KEEP_COUNT=1 # 本地保留最近 N 份
# --- 网盘 1: OneDrive ---
REMOTE1_NAME="onedrive" # rclone remote 名称
REMOTE1_DIR="VPS_Backups/Docker" # 远程目标目录
# --- 网盘 2: Google Drive ---
REMOTE2_NAME="gdrive" # rclone remote 名称
REMOTE2_DIR="VPS_Backups/Docker" # 远程目标目录
REMOTE_KEEP_COUNT=4 # 网盘各保留最近 N 份
# --- Telegram ---
TG_BOT_TOKEN="你的BotToken" # Bot Token
TG_CHAT_ID="你的ChatID" # 你的 Chat ID
TG_ENABLED=true # 是否启用通知
# --- 数据库专用导出 ---
DB_DUMP_ENABLED=true # 是否启用数据库自动检测
# --- GPG 加密 ---
ENCRYPT_ENABLED=false # 是否启用加密
ENCRYPT_PASSPHRASE="" # 加密密码(留空不加密)BOT_TOKEN = "你的BotToken"
ALLOWED_CHAT_ID = 你的ChatID| 🎮 命令 | 🧩 功能 | 说明 |
|---|---|---|
/start |
欢迎消息 | 显示可用命令列表 |
/status |
查看备份状态 | 最近一次备份的完整统计(容器数 / DB 导出数 / 文件大小 / 上传状态) |
/run |
手动触发备份 | 实时回显 bf.sh 执行进度 |
/help |
帮助信息 | 命令说明 |
/root/bf/
├── 📜 bf.sh # 主备份脚本
├── 📜 db_dump.sh # 数据库检测 + 导出模块
├── 📜 restore.sh # 一键恢复脚本
├── 📜 tg_bot.py # Telegram Bot 脚本
├── 📜 tg_bot.service # systemd 服务文件
├── 📜 install_bot.sh # Bot 一键部署脚本
├── 📜 README.md # 本文档
├── 📜 .gitignore # Git 忽略规则
├── 📁 venv/ # Python 虚拟环境 (install_bot.sh 创建)
├── 📄 backup_status.json # 最近一次备份状态 JSON
└── 📁 VPS_Backups/ # 本地备份存放目录
└── 📦 docker_backup_*.tar.gz # 备份文件(本地保留最新 N 份)
🤖 卸载 Telegram Bot
systemctl stop tg_bot
systemctl disable tg_bot
rm -f /etc/systemd/system/tg_bot.service
systemctl daemon-reload⏰ 删除定时任务
crontab -l | grep -v '/root/bf/bf.sh' | crontab -📂 删除项目文件
rm -rf /root/bf📋 删除备份日志
rm -f /var/log/docker_backup.log⚡ 一键卸载(复制整段到终端执行):
systemctl stop tg_bot 2>/dev/null
systemctl disable tg_bot 2>/dev/null
rm -f /etc/systemd/system/tg_bot.service
systemctl daemon-reload
crontab -l 2>/dev/null | grep -v '/root/bf/bf.sh' | crontab -
rm -rf /root/bf
rm -f /var/log/docker_backup.log
echo "✅ 卸载完成"cd /root/bf
git pull
chmod +x *.sh🌐 Q: git clone 失败(国内服务器)?
# 方式一:使用镜像站
git clone https://ghproxy.com/https://github.com/Agff45/vps_docker-bf.git bf
# 方式二:使用代理
git config --global http.proxy http://127.0.0.1:端口
git config --global https.proxy http://127.0.0.1:端口
git clone https://github.com/Agff45/vps_docker-bf.git bf📝 Q: 脚本报 syntax error?
sed -i 's/\r$//' /root/bf/*.sh原因:Windows 换行符
\r\n与 Linux 不兼容。
📦 Q: 备份时提示缺少依赖?
apt install -y jq tar gzip curl rclone☁️ Q: 网盘上传失败?
确认 rclone remote 已正确配置:
rclone lsd onedrive:
rclone lsd gdrive:💡 如果不想用网盘,上传失败不影响本地备份。
🤖 Q: Bot 启动失败?
journalctl -u tg_bot -n 50 # 查看错误日志
systemctl restart tg_bot # 重试启动常见原因:Token 错误、网络不通、Python 依赖未安装。
🐳 Q: 恢复时容器启动失败?
一般为镜像未拉取或网络不存在,手动处理后重试:
docker pull <镜像名>
docker network create <网络名> # 如果 restore.sh 未能自动创建
./restore.sh <备份文件>🗄️ Q: 数据库导出失败怎么办?
备份日志中会显示 ⚠️ [容器名] 导出失败,将回退到卷打包方式 以及 🔍 错误详情。
常见原因和解决方案:
| 症状 | 原因 | 解决 |
|---|---|---|
mysqldump: command not found |
精简镜像不含客户端 | 回退卷打包,或换用完整镜像 |
| 密码为空导出失败 | 环境变量缺失 | 回退卷打包 |
| pg_dumpall 报权限错误 | 非超级用户 | 回退卷打包 |
| MongoDB 无认证导出失败 | 不支持空密码场景 | 回退卷打包 |
🔐 Q: GPG 加密提示 "未设置密码,跳过加密"?
ENCRYPT_ENABLED=true 但没有设置 ENCRYPT_PASSPHRASE。设置密码即可:
nano /root/bf/bf.sh
# 修改: ENCRYPT_PASSPHRASE="你的密码"🌐 Q: 自定义网络容器恢复后网络不存在?
restore.sh 已自动处理此场景 — 恢复时会检测网络是否存在,不存在则自动 docker network create。
如果还是失败,手动创建即可:
docker network create <网络名>Made with ❤️ for VPS & Docker users