- 云原生
- 运维
- 后端
- 容器编排
【免费下载链接】all-in-one
📦 The official Nextcloud installation method. Provides easy deployment and maintenance with most features included in this one Nextcloud instance.
导读
本指南以 Nextcloud All-in-One(AIO)的实例恢复能力为核心,系统讲解如何利用 borgbackup 容器生成的加密备份归档,在全新或故障实例上完整还原整个 Nextcloud 环境。文章覆盖本地备份目录与远程 SSH 仓库两种恢复场景的完整操作流程、路径与密码校验规则、SSH 公钥授权机制,以及恢复背后的底层实现原理(rsync / borg extract 双策略与配置保护逻辑),帮助读者理解并安全地完成一次端到端实例恢复。文中所有操作细节均对应仓库内的人工 QA 测试计划 tests/QA/010-restore-instance.md 与相关源码实现。
恢复前置条件:备份归档、位置与密码
要执行实例恢复,首先需要同时具备三样东西:
- 一份 AIO 实例的备份归档:由 AIO 内置的 borgbackup 容器生成,归档命名遵循
日期-nextcloud-aio的约定(如2026-09-30T03:00:00-nextcloud-aio)。仓库的 QA 测试计划在 tests/QA/assets/backup-archive/readme.md 中说明了测试归档的存放方式——由于 Git LFS 大小限制,备份归档被迁移到外部云盘托管,实际使用时可自行准备归档文件。 - 归档所在的位置:可以是宿主机上的本地目录(例如
/mnt/backup),也可以是远程 SSH 主机上的 Borg 仓库(例如ssh://user@host:port/path/to/repo)。 - 归档的加密密码:即创建备份时使用的 Borg 仓库加密口令(
repokey-blake2加密,见 Containers/borgbackup/backupscript.sh)。密码一旦丢失将无法解密归档,必须妥善保管。
恢复入口位于 AIO 管理界面的初始配置页:当实例尚未配置备份位置时,页面会同时提供"新建 AIO 实例"与"从备份恢复旧 AIO 实例"两个区块(见 php/templates/containers.twig)。
恢复界面:三个输入字段与路径要求
恢复表单包含三个输入字段,对应 php/templates/containers.twig 中的三个 POST 参数:
| 字段 | 表单 name | 示例 / 说明 |
|---|---|---|
| 本地备份位置 | borg_restore_host_location | /mnt/backup(宿主机目录)或 Docker 卷名nextcloud_aio_backupdir |
| 远程 Borg 仓库 | borg_restore_remote_repo | ssh://user@host:port/path/to/repo或user@host:/path/to/repo |
| Borg 加密口令 | borg_restore_password | 创建归档时设置的加密密码 |
这三个参数经由 php/src/Controller/ConfigurationController.php 读取后,交给ConfigurationManager::setBorgRestoreLocationVarsAndPassword()处理(php/src/Data/ConfigurationManager.php),期间会执行严格的路径校验:
本地路径校验规则(validateBorgLocationVars,php/src/Data/ConfigurationManager.php):
- 本地路径必须以
/开头且不能以/结尾(/mnt/backup合法,/mnt/backup/非法); - 也可以使用 Docker 卷名
nextcloud_aio_backupdir; - 本地路径与远程仓库二者互斥,不能同时填写,也不能都为空;
- 路径不能是 NEXTCLOUD_DATADIR 本身或其子目录,否则恢复时归档会被 Nextcloud 数据目录一并删除(对应 php/src/Data/ConfigurationManager.php 中的防护逻辑)。
远程仓库校验规则(validateBorgRemoteRepo,php/src/Data/ConfigurationManager.php):
- 远程 URL 中必须同时包含
@和:,否则直接抛出InvalidSettingConfigurationException。例如user(缺@和:)会被拒绝,而user@host:/path与ssh://user@host:22/path均合法; - 校验通过后,三个值会被持久化,同时将
instance_restore_attempt置为true,让界面进入"恢复尝试中"状态。
从本地备份位置恢复:完整操作流程
错误路径 / 错误密码的容错流程
QA 测试计划(tests/QA/010-restore-instance.md)要求系统对错误输入保持"可继续调试"的容错性:
- 输入错误路径(如不存在的目录)或错误密码,提交后点击Test path and encryption(测试路径和加密);
- 测试容器运行失败后页面刷新,回到初始界面并显示Last test failed!(最近一次测试失败)状态;
- 用户可以点击链接查看
nextcloud-aio-borgbackup容器的日志,定位具体失败原因; - 失败状态下三个输入框会重新出现,允许修改路径或密码后再次提交测试。
这一流程在自动化测试 php/tests/tests/restore-instance.spec.js 中得到了完整覆盖:测试先以不存在的路径/tmp/test/aio-incorrect-path提交,再以错误密码foobar提交,两次均断言界面出现 "Last test failed!" 文本。底层失败判定依赖备份容器退出码:mastercontainer 通过 php/src/Docker/DockerActionManager.php 中的GetBackupcontainerExitCode()读取nextcloud-aio-borgbackup容器的 ExitCode,非 0 即在界面标记失败(见 php/templates/containers.twig)。
测试模式(test)做了什么?点击测试按钮后,php/src/Controller/DockerController.php 中的StartBackupContainerTest()先将backupMode置为test、清除instanceRestoreAttempt,随后停止所有容器并启动 borgbackup 容器。备份脚本在 test 模式下(Containers/borgbackup/backupscript.sh)会:
- 本地位置:检查给定目录下存在名为
borg的子文件夹,且其中存在 Borg 仓库的config文件; - 远程位置:执行
borg info验证能否连接仓库; - 最后执行
borg list并检查归档列表是否包含nextcloud-aio关键字,确认这是 AIO 生成的合法归档。
正确路径与密码的恢复流程
输入正确的本地路径与密码后,完整的恢复链路如下(对应 QA 计划第 10-16 行):
- 提交并测试:页面刷新后,除 "Test path and encryption" 外的所有选项被隐藏;
- 测试成功:界面显示Last test successful!,同时出现两个新选项——Check backup integrity(检查备份完整性)与备份归档下拉列表(按时间从新到旧排列);
- 完整性检查(可选但推荐):点击后弹出确认窗口(可取消),随后 borgbackup 容器以
check模式运行borg check -v --verify-data(Containers/borgbackup/backupscript.sh),耗时取决于归档大小。检查通过后界面报告Last check successful!,并仅保留"选择归档并恢复"的选项;若检查失败,界面会提示归档可能损坏,并提供Check and repair backup integrity(borg check --repair,见 php/templates/containers.twig)的修复入口; - 选择归档并恢复:在下拉框中选择目标归档(下拉值取自
selected_restore_time,以 UTC 时间显示,来自 php/templates/containers.twig),可勾选Exclude previews from restore加快恢复速度(该选项会触发一次预览目录扫描,见 php/templates/containers.twig),然后点击Restore selected backup,弹出确认窗口(可取消); - 等待恢复完成:恢复完成后页面自动刷新,回到常规容器管理界面,所有容器呈stopped(已停止)状态,并重新出现Start and update containers按钮。
关于归档下拉列表:它由start.sh在每次备份容器运行结束后生成——borg list | grep "nextcloud-aio"的结果写入 mastercontainer 卷中的backup_archives.list(见 Containers/borgbackup/start.sh),前端通过ConfigurationManager::getBackupTimes()读取并反转数组保证最新归档排在最前(php/src/Data/ConfigurationManager.php)。
从远程 SSH 位置恢复:密钥授权流程
远程恢复与本地恢复的区别在于:AIO 需要先与远程 SSH 主机建立信任关系。QA 测试计划(tests/QA/010-restore-instance.md)给出了标准流程:
- 填写远程仓库 URL 与密码:URL 必须形如
ssh://user@host:port/path/to/repo或user@host:/path/to/repo(必须含@与:);若填写user这类不含@/:的无效 URL,提交时应立即收到错误提示(由前述validateBorgRemoteRepo校验兜底); - 首次连接自动生成 SSH 密钥对:borgbackup 容器启动时检测到远程仓库且密钥文件不存在,会自动执行
ssh-keygen -f "$BORGBACKUP_KEY" -N ""生成密钥对(Containers/borgbackup/backupscript.sh),密钥持久化存储在 mastercontainer 卷的data/id_borg路径(见 Containers/borgbackup/start.sh); - 获取并授权公钥:首次连接尝试失败后,界面会显示生成的 SSH 公钥(
borg_public_key,渲染于 php/templates/containers.twig),提示"你仍需要在该远程主机上授权此公钥";将该公钥追加到远程服务器目标用户的~/.ssh/authorized_keys文件中; - 再次测试:授权完成后,回到页面重新点击测试按钮,此时
borg info与borg list应能成功连接远程仓库,界面进入与本地恢复相同的后续流程(完整性检查 → 选择归档 → 恢复)。
底层实现上,SSH 连接由 Containers/borgbackup/start.sh 中的环境变量配置驱动:BORG_REPO被设为远程 URL,BORG_RSH使用ssh -o StrictHostKeyChecking=accept-new -i $BORGBACKUP_KEY,即首次连接时自动接受远端主机指纹(accept-new)。远程归档的密码通过BACKUP_RESTORE_PASSWORD环境变量注入并导出为BORG_PASSPHRASE(Containers/borgbackup/start.sh);若BORG_PASSWORD与BACKUP_RESTORE_PASSWORD均未设置,容器会直接报错退出。这些环境变量由 mastercontainer 的 php/src/Data/ConfigurationManager.php 中getPlaceholderValue()统一注入(BORGBACKUP_REMOTE_REPO、BORGBACKUP_MODE、BACKUP_RESTORE_PASSWORD、BORGBACKUP_HOST_LOCATION、SELECTED_RESTORE_TIME、RESTORE_EXCLUDE_PREVIEWS等)。
恢复的底层实现:两种数据还原策略与配置保护
当backupMode被置为restore后,php/src/Controller/DockerController.php 中的StartBackupContainerRestore()会先以forceStopNextcloud = true递归停止全部容器(其中 Collabora 会被优先停止以强制保存文档),随后启动 borgbackup 容器。真正执行还原的逻辑位于 Containers/borgbackup/backupscript.sh,其关键设计如下:
归档选择:若指定了SELECTED_RESTORE_TIME,则从borg list中匹配该时间点的nextcloud-aio归档;否则自动选取最新归档。
本地 vs 远程的差异化还原策略:
- 本地归档:先
borg mount挂载归档到/tmp/borg,再用rsync --delete同步回/nextcloud_aio_volumes/,期间排除 Caddy 配置、证书、会话文件、日志与configuration.json等运行时敏感项(Containers/borgbackup/backupscript.sh); - 远程归档:由于
borg mount对远程仓库较慢,改用borg extract直接就地解包,随后用find+comm对比归档清单,删除本地存在但归档中不存在的文件(保证还原后目录与备份完全一致,见 Containers/borgbackup/backupscript.sh)。
数据排除规则:脚本会检测 Nextcloud 数据目录中的.noaiobackup标记文件(存在则整个数据目录或预览目录被排除备份/还原),并支持通过RESTORE_EXCLUDE_PREVIEWS排除预览图以加速恢复;排除预览后会在还原结束时写入trigger-preview.scan标记,触发 Nextcloud 容器下次启动时重建预览索引(Containers/borgbackup/backupscript.sh、Containers/borgbackup/backupscript.sh)。
配置文件的"恢复后再保护":还原完成后,脚本会通过jq重新写入configuration.json,把backup-mode置回restore,并将当前实例的备份位置、远程仓库、AIO 管理密码(passphrase)与 nextcloud_datadir 恢复为还原前正在使用的值——换言之,归档中保存的旧 AIO passphrase不会被恢复(这与界面提示"当前 AIO passphrase 将被保留"一致,见 php/templates/containers.twig);同时额外备份目录列表与每日备份时间也会被保留(Containers/borgbackup/backupscript.sh)。
还原后的自检与收尾:
- 校验还原后的
configuration.json必须包含domain与wasStartButtonClicked字段,否则判定归档本身不完整并失败退出(Containers/borgbackup/backupscript.sh); - 写入
skip.update(跳过下次 Nextcloud 更新)与fingerprint.update(下次启动重新生成文件指纹)标记(Containers/borgbackup/backupscript.sh); - 删除 Redis 的
dump.rdb缓存文件,避免还原后读到脏缓存(Containers/borgbackup/backupscript.sh)。
另外,mastercontainer 的每日备份脚本 Containers/mastercontainer/daily-backup.sh 会在检测到configuration.json中backup-mode为restore时主动退出,避免恢复过程中触发定时备份造成干扰。若恢复的备份中包含社区容器(community container),界面会特别提示:需要再执行一次同样的恢复,社区容器数据才能被正确还原(php/templates/containers.twig)。
恢复完成后的收尾与验证
恢复完成、页面回到容器管理界面后,QA 计划(tests/QA/010-restore-instance.md)要求:
- 点击Start and update containers时弹出确认窗口,提示应先创建备份——取消则中止,确认则显示全屏加载动画(大 spinner)并启动全部容器;
- 等待一段时间后,所有容器状态变为绿色(healthy),实例完全恢复可用。
这一完整链路同样被自动化 E2E 测试覆盖: php/tests/tests/restore-instance.spec.js 依次执行"检查完整性 → 接受对话框 → 恢复选中备份 → 断言 'Last restore successful!' → 点击 Start and update containers → 断言 'Open your Nextcloud ↗' 链接出现",最终还会验证恢复出的实例密码与初始密码一致,并确认容器可被正常停止。若恢复过程中断或失败,界面会显示Last restore failed!并引导用户调整路径与密码后重试(php/templates/containers.twig)。
延伸阅读
- 备份与恢复的日常管理(手动备份、完整性检查、每日自动备份时间、附加备份目录等):tests/QA/020-backup-and-restore.md
- 恢复界面的完整模板实现:php/templates/containers.twig
- 恢复 / 测试 / 检查的控制器入口:php/src/Controller/DockerController.php
- 路径与远程仓库的校验逻辑:php/src/Data/ConfigurationManager.php
- Borg 还原脚本主体:Containers/borgbackup/backupscript.sh 与容器入口 Containers/borgbackup/start.sh
- 云原生
- 运维
- 后端
- 容器编排
【免费下载链接】all-in-one
📦 The official Nextcloud installation method. Provides easy deployment and maintenance with most features included in this one Nextcloud instance.
相关推荐
Borg 磁盘镜像备份实战:从整盘归档到瘦身还原的完整指南
Borg 磁盘镜像备份实战:从整盘归档到瘦身还原的完整指南 导读 本文讲解如何用 Borg(Deduplicating archiver)对整个物理磁盘、分区乃
运维存储Nextcloud AIO 迁移实战指南:从已有 Nextcloud 实例平滑迁移到 All-in-One
Nextcloud AIO 迁移实战指南:从已有 Nextcloud 实例平滑迁移到 All in One 本文是 Nextcloud AIO(All in O
云原生运维后端容器编排Borg `borg extract` 命令完全指南:从归档恢复文件与裸设备
Borg borg extract 命令完全指南:从归档恢复文件与裸设备 导读 borg extract 是 Borg(Deduplicating archiv
运维存储
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考