一个基于cron的简单备份镜像,用于vaultwarden。
⚠️ 由于Bitwarden_RS已重命名为Vaultwarden,本项目也更名为vaultwarden-backup。为方便起见,我会继续将镜像推送到旧的Docker仓库,但建议您抽空切换到新仓库 <[***]>,只需将 bruceforce/bw_backup 镜像替换为 bruceforce/vaultwarden-backup 即可。
您可能会问:“既然可以将Vaultwarden文件包含在常规备份中,为什么还要用容器来备份?” 使用常规备份软件备份数据库时,一个注意事项是:应在备份前停止数据库服务器,否则可能导致数据丢失。因此,需要使用正确的数据库备份命令。
当然,您也可以在主机上创建cron任务,例如 sqlite3 "$VW_DATABASE_URL" ".backup '$BACKUP_FILE_DB'",并使用首选备份解决方案备份其他文件和文件夹(如附件文件夹)。
但在某些系统上,您无法自行添加cron任务(例如常见的NAS厂商不允许),这就是本镜像存在的原因。此外,它还会包含最重要的文件并将其打包为 tar.xz 归档文件,方便您的常规备份软件处理。
默认情况下,备份包含Vaultwardenwiki <[]> 推荐的所有文件。您可以通过环境变量修改此行为。
从v0.0.7版本开始,您可以始终使用 latest 标签,因为镜像支持多架构。当然,您也可以使用版本标签 vx.y.z 以固定到特定版本。但请注意,固定版本后,alpine基础镜像将不会收到安全更新。
确保您的vaultwarden容器名称为 vaultwarden,否则需要在 docker run 命令的 --volumes-from 部分替换容器名称。
容器内运行cron守护进程,容器将在后台持续运行。
最简单的使用方式是调整 docker-compose.yml 以满足您的需求。以下是使用 docker run 的示例命令:
使用默认设置启动备份容器(每天凌晨5点自动备份)
shdocker run -d --restart=always --name vaultwarden-backup --volumes-from=vaultwarden bruceforce/vaultwarden-backup
每小时备份示例
shdocker run -d --restart=always --name vaultwarden-backup --volumes-from=vaultwarden -e CRON_TIME="0 * * * *" bruceforce/vaultwarden-backup
30天后删除旧备份示例
shdocker run -d --restart=always --name vaultwarden-backup --volumes-from=vaultwarden -e TIMESTAMP=true -e DELETE_AFTER=30 bruceforce/vaultwarden-backup
您可以使用主机的crontab调度备份,容器仅在备份过程中运行。
shdocker run --rm --volumes-from=vaultwarden bruceforce/vaultwarden-backup manual
如果希望备份文件存储在容器外部,需要挂载目录,添加 -v <主机路径>:<容器内路径>。完整命令示例:
shdocker run --rm --volumes-from=vaultwarden -e UID=0 -e BACKUP_DIR=/myBackup -e TIMESTAMP=true -v $(pwd)/myBackup:/myBackup bruceforce/vaultwarden-backup manual
请记住,命令在容器内执行。因此 $BACKUP_DIR 可以是容器内的任何位置。最简单的方式是设置为 /data/backup,这会在原始数据库文件旁边创建备份。
备份tar.xz归档文件可以选择加密。如果您在保险库中存储敏感附件(如ssh密钥)并将备份保存在不受信任的位置,这会很有用。
由于我们使用tar命令(Linux系统上最常见),而tar本身没有加密标志,因此使用gpg加密tar.xz归档文件。有两种加密方式:对称和非对称,只能选择一种。如果同时设置两种环境变量,将仅执行非对称加密。
最简单的加密方式是使用密码进行对称加密。通过设置环境变量 ENCRYPTION_PASSWORD=<您的密码> 实现。
在某些情况下,将密码存储为环境变量可能不合适,此时可以使用gpg公钥加密备份。
另一种加密方式是使用gpg公钥。公钥需要提供为无换行的base64字符串。在大多数系统上,可以通过 base64 -w 0 公钥路径.asc 生成。然后设置环境变量 ENCRYPTION_BASE64_GPG_KEY 为生成的base64编码公钥。
要解密文件,运行 gpg --decrypt backup.tar.xz.gpg > backup.tar.xz。此命令适用于两种加密方式。如果使用gpg公钥加密,需先将gpg密钥对导入本地密钥环;对称加密只需输入密码。
为防止意外数据丢失,没有自动恢复流程。如需恢复备份,请手动执行以下步骤(假设备份位于 ./backup/,vaultwarden数据位于 /var/lib/docker/volumes/vaultwarden/_data/):
sh# 删除现有sqlite3文件 rm /var/lib/docker/volumes/vaultwarden/_data/db.sqlite3* # 提取归档文件(可能需要先安装xz) tar -xJvf ./backup/data.tar.xz -C /var/lib/docker/volumes/vaultwarden/_data/
默认值参见 src/opt/scripts/set-env.sh
| ENV | 描述 |
|---|---|
| APP_DIR | 容器内的应用目录(不应修改) |
| APP_DIR_PERMISSIONS | 容器内应用目录的权限(不应修改) |
| BACKUP_ADD_DATABASE 1 | 设为 true 以在备份中包含数据库本身 |
| BACKUP_ADD_ATTACHMENTS 1 | 设为 true 以在备份中包含附件文件夹 |
| BACKUP_ADD_CONFIG_JSON 1 | 设为 true 以在备份中包含 config.json |
| BACKUP_ADD_ICON_CACHE 1 | 设为 true 以在备份中包含图标缓存文件夹 |
| BACKUP_ADD_RSA_KEY 1 | 设为 true 以在备份中包含RSA密钥 |
| BACKUP_ADD_SENDS 1 | 设为 true 以在备份中包含sends文件夹 |
| BACKUP_DIR | 容器内备份文件夹路径 |
| BACKUP_DIR_PERMISSIONS | 备份文件夹权限(注意 2)。设为-1禁用 |
| BACKUP_ON_STARTUP | 容器启动后立即创建备份 |
| CRONFILE | 容器内cron文件路径 |
| CRON_TIME | cron任务格式 "分 时 日 月 周 年" |
| DELETE_AFTER | X天后删除旧备份。设为0禁用 |
| ENCRYPTION_ALGORITHM 3 | 对称加密算法(仅与ENCRYPTION_PASSWORD一起使用) |
| ENCRYPTION_BASE64_GPG_KEY | BASE64编码的gpg公钥。设为 false 禁用 |
| ENCRYPTION_GPG_KEYFILE_LOCATION | 容器内gpg公钥文件路径(不应修改) |
| ENCRYPTION_PASSWORD | 对称加密密码。设为 false 禁用 |
| TIMESTAMP | 设为 true 以在备份文件名后附加时间戳 |
| GID | 运行cron任务的组ID |
| GNUPGHOME | 容器内GNUPG主目录(不应修改) |
| GNUPGHOME_PERMISSIONS | GNUPG主目录权限(不应修改) |
| HEALTHCHECK_URL | 设置健康检查URL,如 <[***]> |
| HEALTHCHECK_FILE | 本地健康检查(容器健康)文件路径 |
| HEALTHCHECK_FILE_PERMISSIONS | 本地健康检查(容器健康)文件权限 |
| LOG_LEVEL | 支持DEBUG、INFO、WARNING、ERROR、CRITICAL |
| LOG_DIR | 容器内日志文件文件夹路径 |
| LOG_DIR_PERMISSIONS | 日志文件文件夹权限。设为-1禁用 |
| TZ | 设置容器内时区 4 |
| UID | 运行cron任务的用户ID |
| VW_DATA_FOLDER 5 | 容器内vaultwarden数据文件夹位置 |
| VW_DATABASE_URL 5 | 容器内vaultwarden数据库文件位置 |
| VW_ATTACHMENTS_FOLDER 5 | 容器内vaultwarden附件文件夹位置 |
| VW_ICON_CACHE_FOLDER 5 | 容器内vaultwarden图标缓存文件夹位置 |
Error: unable to open database file 很可能是权限错误。注意,sqlite3在备份时会在源目录创建锁文件,因此源目录和目标目录都需要对用户有读写权限。可通过上述 UID 和 GID 环境变量设置用户和组ID。
Error: database is locked 很可能是因为备份位置与vaultwarden数据库不在同一文件系统(如网络文件系统)。
默认情况下,Vaultwarden使用WAL(预写日志)。可通过检查数据库文件同目录是否存在 db.sqlite3-wal 文件确认。根据SQLite文档,WAL在网络共享场景下会出现问题(参见 []
所有使用数据库的进程必须在同一主机上;WAL不支持网络文件系统。
有两种解决方法:
cp 或 rsync 等工具将备份文件复制到网络文件系统。如需备份文件名的时间戳使用本地时区,应挂载 /etc/timezone:/etc/timezone:ro 和 /etc/localtime:/etc/localtime:ro,如 docker-compose.yml 所示。另一种方法是设置环境变量(如 TZ=Asia/Shanghai)(参见 <[***]>)。
注意 如使用ARM平台,本项目基于alpine构建以保持轻量。alpine 3.13及以上版本在ARM平台可能出现时间日期错误(如显示1900年)。这是alpine已知问题(参见 Github issue 和 解决方案)。alpine wiki中提供了修复方案,我已在树莓派上测试有效。如应用修复后仍有问题,可提交issue。
构建此镜像的主要目的是让用户在无法添加cron任务的主机系统上,或需要不依赖主机OS机制的“可移植”调度任务时使用。
由于 crond 必须 以root用户运行,因此使用cron时无法以非root用户启动容器。我知道有其他任务调度器(如 supercronic)支持非root运行,但目前仍选择使用标准成熟的cron系统。
Alpine默认未安装bash。预装的 ash shell足以满足本镜像的任务需求,且无需额外安装bash等工具,因此使用 /bin/sh。脚本也力求符合POSIX标准,以便在需要时轻松切换基础镜像。
来自真实用户的反馈,见证轩辕镜像的优质服务
免费版仅支持 Docker Hub 加速,不承诺可用性和速度;专业版支持更多镜像源,保证可用性和稳定速度,提供优先客服响应。
免费版仅支持 docker.io;专业版支持 docker.io、gcr.io、ghcr.io、registry.k8s.io、nvcr.io、quay.io、mcr.microsoft.com、docker.elastic.co 等。
当返回 402 Payment Required 错误时,表示流量已耗尽,需要充值流量包以恢复服务。
通常由 Docker 版本过低导致,需要升级到 20.x 或更高版本以支持 V2 协议。
先检查 Docker 版本,版本过低则升级;版本正常则验证镜像信息是否正确。
使用 docker tag 命令为镜像打上新标签,去掉域名前缀,使镜像名称更简洁。
探索更多轩辕镜像的使用方法,找到最适合您系统的配置方式
通过 Docker 登录认证访问私有仓库
在 Linux 系统配置镜像加速服务
在 Docker Desktop 配置镜像加速
Docker Compose 项目配置加速
Kubernetes 集群配置 Containerd
在宝塔面板一键配置镜像加速
Synology 群晖 NAS 配置加速
飞牛 fnOS 系统配置镜像加速
极空间 NAS 系统配置加速服务
爱快 iKuai 路由系统配置加速
绿联 NAS 系统配置镜像加速
QNAP 威联通 NAS 配置加速
Podman 容器引擎配置加速
HPC 科学计算容器配置加速
ghcr、Quay、nvcr 等镜像仓库
无需登录使用专属域名加速
需要其他帮助?请查看我们的 常见问题 或 官方QQ群: 13763429