从 strfry 迁移
用一条命令将现有 strfry 中继的事件迁移到 nostrfy — 准备、dry-run、迁移、验证和回滚。
一览
nostrfy migrate-strfry 读取 strfry 自己的导出格式(JSONL,每行一个 NIP-01 事件),因此可跨 strfry 数据库版本,且不依赖 strfry
内部的 LMDB schema。它从不写入 strfry 数据库。
| 已迁移 | 未迁移 |
|---|---|
| 每个已存储的事件(应用可替换/可寻址语义) | 没有 nostrfy 等效项的 strfry 设置(合并报告会列出每一项及原因) |
| NIP-40 过期 — 已过期的事件被跳过 | Blossom 媒体及其所有者映射(strfry 没有 Blossom 服务器) |
| NIP-09 删除,包括 strfry 已物理删除的事件的重新发布阻止 | 访问列表(NIP-86 封禁、中继公钥列表、Blossom 白名单) |
NIP-29 9005/9008 管理副作用 | NIP-43 邀请码(用 createclaim 签发新的) |
| 首次出现时间戳(配置了新公钥门槛时) | NIP-62 消除请求,除非给出 --apply-vanish |
| NIP-29 群组、NIP-43 角色及其中继签名元数据,在首次启动时重建 | 中继自身的身份/密钥(它们位于 nostrfy.toml) |
等效的 strfry 设置,可选择合并到 nostrfy.toml |
摘要中的预期跳过:临时事件(类型 20000-29999,nostrfy 从不存储)和 已过期事件。
快速开始
# 1. 停止 nostrfy 中继(迁移需要数据库目录)
nostrfy --config /etc/nostrfy/nostrfy.toml stop
# 2. dry run — 解析并验证每个事件,不写入任何内容
nostrfy --config /etc/nostrfy/nostrfy.toml migrate-strfry \
--strfry-db /var/lib/strfry-db --dry-run
# 3. 导入
nostrfy --config /etc/nostrfy/nostrfy.toml migrate-strfry \
--strfry-db /var/lib/strfry-db
# 4. 启动 — NIP-29 群组和 NIP-43 角色从导入的事件重建
nostrfy --config /etc/nostrfy/nostrfy.toml start环境要求
strfry二进制(用于--strfry-db),或你自己导出的 JSONL 文件。- nostrfy v0.1.15 或更高版本(
migrate-strfry子命令)。 - 目标中继的 nostrfy 配置,已设置
database.path、public_url和private_key。 - 空闲磁盘空间:大约为 strfry 导出加上其索引的大小。NIP-50 词索引会增加
一些;磁盘非常紧张时可先禁用(
database.search_index = false), 迁移后再启用(索引在启动时重建)。 - 目标
database.path上没有运行中的 nostrfy 实例。
准备配置
[relay]
name = "My Relay"
public_url = "wss://relay.example.com" # NIP-42/62/98 和 NIP-29 元数据需要
private_key = "..." # NIP-29/43 中继签名元数据需要
[server]
host = "0.0.0.0"
port = 8080
[database]
path = "/var/lib/nostrfy"
map_size = 1073741824如果没有中继密钥,用 nostrfy genkey 生成,然后校验:
nostrfy --config /etc/nostrfy/nostrfy.toml check合并 strfry 设置(可选)
在打开数据库之前,migrate-strfry 会查找 strfry 的配置
(--strfry-config,然后 $STRFRY_CONFIG、/etc/strfry.conf、 ./strfry.conf),打印有 nostrfy 等效项且与你的 nostrfy.toml 不同的设置,并询问是否合并。只重写列出的键 — 注释
和所有其他行都保留,会使配置无效的值会被跳过并说明原因,其余仍然合并。
--merge-config不经询问直接应用(用于脚本);--no-merge-config跳过该步骤。- 没有终端时,会打印建议,除非给出
--merge-config,否则跳过合并。 --dry-run打印建议但从不写入。
Dry run
先看再跳 — dry run 解析并验证整个导出,而不触碰数据库:
nostrfy migrate-strfry --strfry-db /var/lib/strfry-db --dry-run非零的 bad signature 计数意味着导出包含 strfry 未经
校验就接受的事件;它们会被跳过。如果信任它们,传 --no-verify 仍然导入。
迁移
选择三种输入模式之一 — 结果完全相同:
# 选项 A — nostrfy 自己运行 `strfry export`(strfry 在 PATH 中)
nostrfy migrate-strfry --strfry-db /var/lib/strfry-db
# 选项 B — 你自己导出到文件
strfry export > /tmp/strfry-export.jsonl
nostrfy migrate-strfry --input /tmp/strfry-export.jsonl
# 选项 C — 管道(stdin 是默认输入)
strfry export | nostrfy migrate-strfry| 标志 | 用途 |
|---|---|
--strfry-bin <PATH> | strfry 不在 PATH 中 |
--since <UNIX> | 续传/追赶:created_at 为该值或更新的事件(含边界) |
--apply-vanish | 处理导出中发现的 NIP-62 消除请求(默认关闭) |
--no-verify | 对可信转储跳过签名验证(更快) |
--batch <N> | 每个数据库事务的事件数(默认 512) |
--dry-run | 只解析和验证 |
迁移可安全重复运行:重复项被跳过,删除副作用会
重新应用,因此中断的运行可以直接重跑(或用 --since 续传)。
启动与验证
首次启动会从导入的事件重建 NIP-29 群组存储和 NIP-43 角色存储,并
重新发布中继签名的元数据(每个群组的 39000/39001/39002/39005,
以及 13534 成员列表)。大型数据库可能需要一会儿;请观察日志。
R=wss://relay.example.com # 用于 nak(WebSocket)
H=https://relay.example.com # 用于 curl(HTTP)
nak relay "$R" # 中继响应并公布其 NIP
curl -s "$H/api/v1/query?limit=1" # 事件可被提供
nak req -i <deleted-event-id> "$R" # 已删除的事件保持消失
nak req -k 39000 "$R" # NIP-29 群组元数据(如已迁移)
nak req --auth --force-pre-auth --sec <nsec> -k 13534 "$R" # NIP-43 成员列表(AUTH)如需精确的数量对比,strfry scan '{}' | wc -l 减去迁移摘要中报告的临时/过期事件
应等于客户端能取回的数量。
恢复中断的迁移
- 导出到文件/管道:重新运行同一命令。重复项被跳过,删除 阻止会重新应用。
- 使用了
--strfry-db:摘要会打印续传提示;用那个--since重新运行(含边界,边界秒会重新导入并去重)。 - 如果运行失败并显示
database writer unavailable,检查空闲磁盘空间和database.map_size,然后重跑。
回滚
迁移只写入 nostrfy 数据库。要回滚,停止中继并恢复迁移前的数据库,或将其删除:
nostrfy --config /etc/nostrfy/nostrfy.toml stop
rm -rf /var/lib/nostrfy # 或恢复迁移前的备份故障排除
| 消息 | 原因 / 修复 |
|---|---|
cannot lock the database directory ...; stop the relay before migrating | nostrfy 守护进程(或另一个迁移)占用了目录:先 nostrfy stop |
strfry database directory ... does not exist | --strfry-db 必须指向包含 data.mdb 的目录 |
cannot run 'strfry': ... | 安装 strfry、设置 --strfry-bin,或使用 --input |
database writer unavailable; the migration did not complete | 写入线程停止或队列过载:检查磁盘/映射大小,重跑(安全) |
group purge for <id> did not complete | 清除被中断:重新运行迁移 |
高 bad signature 计数 | strfry 数据库包含未验证的事件:检查它们;仅当信任来源时才用 --no-verify 导入 |
| 启动后缺少 NIP-29 元数据 | 没有 relay.private_key:运行 nostrfy genkey 并重启 |
| 未提供设置合并 | 未找到 strfry 的配置:传 --strfry-config /etc/strfry.conf |
检查清单
- nostrfy 中继已停止
- strfry 数据库和 nostrfy 配置已备份
nostrfy check通过- strfry 设置已合并(或报告已审阅)
- dry run 已审阅(无意外的坏签名)
- 迁移无错误完成
- 中继启动;群组/角色重建已记录
- 事件数量匹配(减去临时/过期)
- 已删除的事件保持消失(重新发布被拒绝)
- 以匿名和成员身份检查了私密群组可见性
- 反向代理 / DNS / 客户端中继列表已更新