目录

将自建Vaultwarden (Bitwarden) 数据库增量备份到github 私有仓库

背景

在自建Vaultwarden (Bitwarden) 时,数据库一般在服务器的某个目录下,肯定要每天备份防止密码数据丢失,我目前是采用rclone备份到腾讯云的对象储存(老用户有免费50G的容量)。今天无意间看见新方法,备份到github仓库,故进行实践。原文

步骤

1. 生成用于 GitHub 的 SSH 密钥(推荐 ed25519)

# 建议用独立文件名,避免覆盖你已有的 id_ed25519
ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/id_ed25519_github

执行后会生成:

私钥:~/.ssh/id_ed25519_github

公钥:~/.ssh/id_ed25519_github.pub

2. 设置该密钥 Host 别名

目的是为了安全,该仓库在推送时使用这个密钥,而不默认使用账户级别的密钥。

~/.ssh/config 加一段

vi ~/.ssh/config
Host github-vw-backup
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_github
  IdentitiesOnly yes

3. 复制公钥

cat ~/.ssh/id_ed25519_github.pub

把输出整行复制(以 ssh-ed25519 开头)。

上传到 GitHub 私有仓库,来备份数据库

  1. 新建仓库
    具体步骤略过… https://s3.aixfan.com/img/screenshot/2026/01/15/1768481031_99b.png

  2. 将公钥添加到 GitHub 仓库的部署密钥

注意: 这里是添加到仓库的部署密钥,不是添加到你 GitHub 账号的 SSH 密钥!!!
仓库 -> Settings -> Deploy keys -> Add deploy key (需要勾选 Allow write access )
此步骤是为了安全性考虑。
https://s3.aixfan.com/img/screenshot/2026/01/15/1768481074_100b.png https://s3.aixfan.com/img/screenshot/2026/01/15/1768481115_101b.png

3. 初始化本地仓库

cd /path/to/your/project
git init
git add .
git commit -m "Initial backup"

/path/to/your/project 为vw目录
your_username 为 GitHub 用户名
your_repository 为仓库名。

4. 关联远端仓库并推送

注意:这里使用的是 github-vw-backup,而不是 github.comgithub-vw-backup为第二步设置的别名。

git remote add origin git@github-vw-backup:your_username/your_repository.git
git push -u origin master

执行后,初始数据库就会被推送到 GitHub 仓库了。


5. 编写备份脚本

vi /usr/local/bin/vw_backup.sh
#!/usr/bin/env bash
set -euo pipefail

# ====== 配置 ======
REPO_DIR="/path/to/your/project"
BRANCH="master"
LOG_FILE="/var/log/vw_backup.log"
# 可选:给提交信息加主机名,方便区分多台机器
HOST_TAG="$(hostname -s)"
# ============================

mkdir -p "$(dirname "$LOG_FILE")"

ts() { date "+%Y-%m-%d %H:%M:%S"; }

{
  echo "[$(ts)] backup start: $REPO_DIR"

  cd "$REPO_DIR"

  # 确保在正确分支
  git rev-parse --is-inside-work-tree >/dev/null
  git checkout -q "$BRANCH"

  # 拉一下远端(避免非快进导致 push 失败;如果不希望自动合并,可改成只检测)
  git fetch -q origin "$BRANCH" || true
  # 可选:如果希望本地永远覆盖远端备份,可以用 reset(谨慎)
  # git reset --hard "origin/$BRANCH" || true

  # 只在有变更时才提交
  if [[ -n "$(git status --porcelain)" ]]; then
    git add -A

    # 提交信息里记录时间与主机名
    git commit -m "auto backup $(date +%F\ %T) @${HOST_TAG}" || true

    # 推送
    git push -u origin "$BRANCH"
    echo "[$(ts)] pushed changes."
  else
    echo "[$(ts)] no changes."
  fi

  echo "[$(ts)] backup done."
  echo "----------------------------------------"
} >> "$LOG_FILE" 2>&1

给执行权限:

# 赋予执行权限
chmod +x /usr/local/bin/vw_backup.sh

ps: 最好手动执行一下脚本,确保脚本没有问题

# 手动执行脚本
bash /usr/local/bin/vw_backup.sh

# 查看日志
tail -f /var/log/vw_backup.log

6.设置定时任务

crontab -e

例如: 每天凌晨 2 点执行备份

0 2 * * * /usr/local/bin/vw_backup.sh

例如: 每 30 分钟执行一次备份

*/30 * * * * /usr/local/bin/vw_backup.sh

看日志验证:

tail -f /var/log/vw_backup.log

另一种备份方式(RCLONE)(参考)

1. 下载RCLONE并配置

# 下载
wget https://downloads.rclone.org/rclone-current-linux-amd64.zip
unzip rclone-current-linux-amd64.zip
sudo cp rclone-current-linux-amd64/rclone /usr/local/bin/

# 配置
rclone config

# 后续配置自行查看官方文档

2. 编写本地备份脚本

vi /usr/local/bin/vw_s3_backup.sh
#!/usr/bin/env bash

# 备份目录
DATA_DIR="/path/to/your/project"
# 本地临时存放备份文件的目录
TEMP_DIR="/path/to/your/project/tmp"
# rclone 配置的远端名称和路径
REMOTE="tencent_oss:backup-us-xxxxxxxxxx/my-bitwarden-backups"
# 日志文件路径
LOG_FILE="/var/log/vw_backup_s3.log"

# 时间戳函数
ts() {
  date +"%Y-%m-%d %H:%M:%S"
}

# 确保临时目录和日志目录存在
mkdir -p "$(dirname "$TEMP_DIR")"
mkdir -p "$(dirname "$LOG_FILE")"

{
  echo "[$(ts)] ==> 开始 S3 备份任务"

  # 生成时间戳,作为备份文件名称区分
  TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
  BACKUP_FILE="vaultwarden_${TIMESTAMP}.tar.gz"
  LOCAL_BACKUP_PATH="${TEMP_DIR}/${BACKUP_FILE}"

  # 打包 Vaultwarden 数据目录
  echo "[$(ts)] ==> 开始打包 Vaultwarden 数据目录..."
  tar -czf "${LOCAL_BACKUP_PATH}" -C "${DATA_DIR}" .

  # 将打包好的文件上传到 S3
  echo "[$(ts)] ==> 上传备份文件到 S3..."
  rclone copy "${LOCAL_BACKUP_PATH}" "${REMOTE}"

  # 上传完成后,删除本地临时文件,节省空间
  rm -f "${LOCAL_BACKUP_PATH}"

  # 删除 S3 上 30 天前的备份
  echo "[$(ts)] ==> 清理 S3 上 30 天之前的旧备份..."
  rclone delete --min-age 30d "${REMOTE}"

  echo "[$(ts)] ==> 备份完成并清理旧文件完毕!"
  echo "--------------------------------------------------"
} >> "$LOG_FILE" 2>&1
# 赋予执行权限
chmod +x /usr/local/bin/vw_s3_backup.sh

3. 设置定时任务

vi /etc/crontab
0 3 * * * /usr/local/bin/vw_s3_backup.sh