Appearance
备份与恢复
主方案:静态站点
保存完整版本目录、站点 ZIP、下载清单与 SHA-256、源码提交及版本标签、Nginx 配置和验收记录。本地模型不受 Git 跟踪,必须另存一份;本地 .env.local 也不能依靠源码仓库恢复,更不能放入公开站点 ZIP。
每次上传到新的版本目录,核对 downloads/SHA256SUMS.txt,完成页面、Worker 和模型验收后,再将宝塔网站根目录切换到新目录。保留上一版目录与配置;出现问题时把根目录切回上一版,运行 nginx -t 并平滑重载,再检查文档、下载和演示。先在测试站点演练,不直接覆盖唯一的线上副本。
证书与私钥通过宝塔或独立的加密备份流程保存,不混入公开站点包。记录备份时间、版本、恢复耗时及可接受的数据恢复范围。
可选方案:私有 registry
以下示例仅用于私有 npm,使用 Linux Bash、Docker Compose v2,在仓库 deploy 目录操作。 所有备份包含凭据和内部密钥,应放在权限受限、加密的异地存储;不要将备份提交到 Git 或发布为静态文件。
备份范围
必须一起保存:完整 /verdaccio/storage、verdaccio/config.yaml、Compose、Nginx 模板、.env、实际镜像 digest 和操作记录。 storage 包含包 tarball、元数据、隐藏文件、数据库/内部密钥和 htpasswd;不能仅复制 .tgz。 TLS 私钥与证书由证书管理流程独立加密备份,或明确记录重新签发方式,不混入公开配置包。
下面默认使用模板卷映射,由 Compose 自动选择 .env 中的实际卷,无需手写卷名。 备份会短暂停服:先阻止新请求、停止 registry,完成一致性快照后再启动。 如有其他写入者或外置存储,必须先协调停写,不能只停止一个容器就宣称一致。
sh
umask 077
mkdir -p backups
BACKUP_ID=$(date -u +%Y%m%dT%H%M%SZ)
# 确认 .env 已锁定当前部署 digest,所需镜像已在本机;此处不拉取或升级。
docker compose images --format json > "backups/images-$BACKUP_ID.json"
docker image inspect "$(docker compose images -q registry)" > "backups/registry-image-$BACKUP_ID.json"
docker image inspect "$(docker compose images -q proxy)" > "backups/proxy-image-$BACKUP_ID.json"
docker compose stop proxy registry
docker compose run --rm --no-deps --user 0 \
--volume "$PWD/backups:/backup" --entrypoint tar registry \
-czpf "/backup/storage-$BACKUP_ID.tar.gz" -C /verdaccio/storage .
tar -czpf "backups/config-$BACKUP_ID.tar.gz" \
compose.yaml verdaccio/config.yaml nginx/registry.conf.template .env
sha256sum "backups/storage-$BACKUP_ID.tar.gz" "backups/config-$BACKUP_ID.tar.gz" \
> "backups/checksums-$BACKUP_ID.txt"
docker compose up -ddocker compose images / docker image inspect 应在已部署容器存在时执行;首次部署尚无数据时先建立有效基线。 如果任何步骤失败,先检查退出状态和磁盘空间,不要上传残缺备份为“成功”。停服后的失败需人工决定继续备份或恢复服务。 tar 必须以 . 打包目录内容,保留隐藏数据库/密钥;不要改为 *。 命令在宿主 umask 077 下运行,但容器生成的存储包仍需检查宿主权限并执行 chmod 600 backups/*。 生成校验和只能证明传输完整,不能代替加密和恢复演练。
注意:生产须预先锁定 .env 中的 digest, 让备份辅助容器与当前运行实例使用同一版本;备份过程不是升级过程。
在隔离位置恢复
禁止直接解压覆盖正在服务的原卷,也不要运行 docker compose down -v。 恢复应使用新主机或新的命名卷,并保留原卷以便回退。
- 在可信机器校验备份校验和与来源,先检查 tar 内容是否存在绝对路径、
..或意外链接。 - 建立独立
deploy副本,恢复配置并审核;不要将未经检查的归档解压到任意系统目录。 - 在独立副本的
.env中使用备份记录的镜像 digest,将REGISTRY_STORAGE_VOLUME改为全新的卷名,例如shardx-map-registry-restore-01。禁止与原服务共用卷。 - 为恢复演练准备独立域名/端口或独立主机,避免默认 Compose 项目名、主机端口和生产服务冲突。
假设经过审核的存储归档已放到恢复目录的 backups/storage-restore.tar.gz,且目标卷尚未使用:
sh
# 在隔离主机或指定独立项目名运行;确认 .env 指向新卷。
docker compose -p shardx-map-restore config --quiet
docker compose -p shardx-map-restore run --rm --no-deps --user 0 \
--volume "$PWD/backups:/backup:ro" --entrypoint sh registry -c \
'test -z "$(ls -A /verdaccio/storage)" || { echo "Target volume is not empty; abort" >&2; exit 1; }; tar -xzpf /backup/storage-restore.tar.gz -C /verdaccio/storage && chown -R 10001:65533 /verdaccio/storage && chmod 700 /verdaccio/storage && chmod 600 /verdaccio/storage/htpasswd'
docker compose -p shardx-map-restore up -d若镜像初始化卷时自带文件,空目录保护可能失败:停止操作并核对文件来源,改用真正空的卷;不要删除未知文件绕过检查。 上例的 chown -R 仅作用于容器内已确认的新 storage 卷。若使用自定义镜像,先核对 UID/GID。 不要把不可信归档交给 root 解压。
恢复验收与回退
先检查日志和 HTTPS,再用干净 npm 缓存验证匿名读取已发布的 @shardx-map/sdk@0.1.0, 核对 metadata、tarball integrity 与已保存包校验和;用恢复的账户验证登录及权限,检查私有命名空间不会回源公网。 对照验收清单完成消费项目真实安装与运行。
记录恢复耗时、最新可恢复时间点、未恢复的日志/缓存,以及哪些凭据需要轮换。 验证成功后再切换 DNS/流量。失败时切回原实例/原卷;若升级版本已改写数据,旧镜像应配对升级前备份使用。 备份保留周期与 RPO/RTO 由业务确定,至少安排一次真实恢复演练并保存证据。