GitHub Explorer
📰 公众号已发布 2026-08-24

GitHub推荐:66K stars,Raspberry Pi 能跑:Vaultwarden 是怎么把 Bitwarden 从 10 个容器压成 50MB 单二进制的

GitHub: https://github.com/dani-garcia/vaultwarden

一句话总结

用单个 Rust 二进制(~50–100MB RAM)重新实现 Bitwarden 官方服务端(10+ Docker 容器、≥1.5–2GB RAM),让官方 Bitwarden 浏览器/桌面/移动客户端零修改连接到一个能跑在 Raspberry Pi 上的自托管密码管理服务端。

值得关注的理由

  1. 极致的资源换 UX — 100× RAM 优势换来”官方客户端 UX + 自托管”,填补”Bitwarden 太重、KeePass 又太本地化”的空白象限,是当前自托管密码管理器赛道 66k★ 的事实标准。
  2. 架构层面的工程样本 — Rocket 0.5(异步)+ Diesel(同步)的桥接、Diesel MultiConnection 横跨 SQLite/MySQL/PostgreSQL、OpenDAL 抽象本地/S3、make_config! 宏把 200+ 配置项编进类型系统 —— 这一整套都是中型 Rust 后端的优秀范例。
  3. 「独立却受雇于官方」的诡异治理样本 — 主作者 Daniel García 同时受雇于 Bitwarden 公司去做一个与官方服务端并行的非官方替代实现(AGPL-3.0-only),8.5 年来维持「兼容性 > 特性完整」「承认上游依赖」的克制路线,是研究 open-source/community-driven vs company-driven 张力的活教材。

项目展示

Vaultwarden Logo

Contributors

仅 logo + contributors 合成图 —— 项目本身没有 demo gif / 截图(其价值在于”跑得起来”,肉眼不可见);UI 完全复用官方 Bitwarden 客户端。

项目画像

维度数据
GitHubhttps://github.com/dani-garcia/vaultwarden
Star / Fork66,112 / 3,138(Watchers: 304)
代码行数71,085(Rust 39.6% / JavaScript 30.1% / CSS 16.6% / JSON 5.2% / Handlebars 2.5% / TypeScript 2.1% / SQL 2.0%)
项目年龄102.5 个月(2018-02 首版 → 2026-08 仍在更新)
开发阶段稳定维护(近 365 天 176 commit,月均 ~15)
贡献模式单人主导 + 核心三人组(Daniel 26.6% / BlackDex / jjlin / stefan0xC,合计 ~37%)
热度定位大众热门 × 细分赛道头部(自托管 Bitwarden 客户端生态的事实服务端入口)
质量评级代码优秀 / 文档良好 / 测试不足
LicenseAGPL-3.0-only

作者视角:为什么存在这个项目

创始人/作者背景

Daniel García,Asturias 西班牙独立开发者,2011 年注册 GitHub,账号 15 年。15.4 年账号、1,313 粉丝、28 个公开仓库,vaultwarden 在他所有仓库里以 66k★ vs 次高 387★ 的悬殊比排名第一(投入权重极高)。关键身份设定:他目前受雇于 Bitwarden Inc.(官方母公司),但同时维护这个「非官方替代服务端」—— README 第 136 行明确这种贡献与 Bitwarden 公司保持独立、并由其他维护者审查,这是一种罕见的”内部人对抗自家产品”位置。

问题判断

Bitwarden 在 2017 年把服务端从 C#/Mono 改写为 .NET Core,但自托管栈仍然是 10+ Docker 容器、≥1.5–2GB RAM、必须配合 MSSQL/PostgreSQL —— 对于在 Raspberry Pi / NAS / 小型 VPS 上想自托管密码管理器的个人/家庭用户来说,资源占用与运维复杂度都 over-engineered。其他自托管密码管理器要么没有 Bitwarden 客户端那样的浏览器自动填充 UX(KeePass),要么是为团队协作设计(Passbolt),要么根本不是密码管理器形态(Keycloak)。Daniel 看到的市场缺口是:让市场上 UX 最好的 Bitwarden 客户端,能跑在 100 元的小服务器上。

解法哲学

① 资源最小化是首要约束 —— Rust + 单二进制 + SQLite 默认 + Alpine/MUSL 静态链接,最终镜像能跑 RPi Zero。 ② 客户端兼容性 > 服务端特性完整 —— 不重写客户端 UI,官方客户端改 API 就跟着改服务端;2021 年把项目从 bitwarden_rs 改名 vaultwarden 就是为了跟 Bitwarden 商标保持距离(README:146–147)。 ③ 明确不做什么的清单 —— 官方 Bitwarden 的 enterprise SSO/Directory Sync 等特性 Vaultwarden 故意不做(Issue #246 META「won’t add unless contributed」),仅通过 OpenID Connect 提供有限度的 SSO。 ④ 承认上游依赖 —— README + Wiki 反复请求用户给 Bitwarden 付费以支撑上游工作,这是 open-source 项目中罕见的”指示竞争对手付费”的姿态。

战略意图

是 Daniel 的旗舰核心产品(非基础设施),没有商业意图(AGPL-3.0-only + 无 SaaS/企业版 + 无 open-core 拆分),社区驱动(贡献集中度 26.6%,前 30 人合计,主贡献者排第一),与官方 Bitwarden 路线图反向而行(社区驱动 vs 公司驱动)。

全数据基于 GitHub Repo 元数据 + README + Wiki + DeepWiki,无独立作者博客。

核心价值提炼

创新之处

  1. 用 Rocket 异步 + Diesel 同步桥接模式跑请求/响应(实用 5/5)
    • src/db/mod.rs:30-42 的 run_blocking 包同步 DB 调用进 tokio::spawn_blocking;DbConn request guard 自实现 Arc<Mutex<Option<PooledConnection>>> + 自定义 Drop 异步归还连接;用 semaphore 限制最大并发防止池饥饿。
  2. Diesel MultiConnection derive 横跨三套 SQL 方言(实用 4/5,可迁移 3/5)
    • 单 codebase 跑 SQLite/MySQL/PostgreSQL;代价是 56+55+46 份手写 SQL 迁移(按方言分裂)+ schema 字段类型差异需要 #![cfg] 分支处理。
  3. OpenDAL + s3:// 前缀检测做本地/S3 透明切换(新颖 3/5,实用 4/5)
    • 单 Operator 类型 + dashmap 缓存 Operator,URL 前缀决定走 services-fs 还是 services-s3;S3 模式下用 reqwest 解析 path segments 的 join_path/parent/file_name 是手写的简陋 polyfill。
  4. make_config! 声明宏把 200+ 配置项编进类型系统(新颖 4/5,实用 4/5,可迁移 3/5)
    • 每个字段同时展开成 ConfigBuilder / getter / admin panel ElementData / privacy mask / env var name;def/auto/option/generated 四种「缺值行为」配合 pastey::paste! 把 env var 大写转换;新增 SSO_FOO 不写 default 会编译报错 —— 用类型系统保证 config schema 完整性的极致体现。
  5. proc-macro crate macros/ 做 UuidFromParam / IdFromParam derive(实用 4/5,可迁移高)
    • syn+quote 给 newtype ID 自动实现 Rocket FromParam trait,消除 30+ ID 类型的样板代码。
  6. web-vault digest pinning + 多架构 Docker 矩阵(amd64/arm64/armv7/armv6)(新颖 3/5,实用 5/5)
    • Dockerfile 用 FROM docker.io/vaultwarden/web-vault@{{ vault_image_digest }} AS vault 而非 tag,supply chain attack 面显著缩小;4 个架构 × 2 个 base = 8 个镜像变体,靠 DockerSettings.yaml + Dockerfile.j2 (Jinja2) + docker-bake.hcl 三件套的声明式渲染支撑。
  7. WebAuthn/U2F/Passkey 三阶段迁移(新颖 3/5,实用 3/5)
    • 启动期跑 migrate_u2f_to_webauthn + migrate_credential_to_passkey(main.rs:92-93),用 webauthn-rs 的 danger-allow-state-serialisation 把 state 序列化进 DB(Cargo.toml:155–156 注释解释为何开启 danger feature)。

可复用的模式与技巧

模式适用场景
Rocket 0.5 异步 + Diesel 同步桥接(run_blocking + DbConn 自实现归还)任何”Rocket + 同步 ORM”项目
Diesel MultiConnection derive + 手写 DbConnManager一个 codebase 需要跑多种 SQL 方言
make_config! 声明宏 + admin panel 自动生成配置项 ≥ 50 且需要 admin web self-service
OpenDAL + scheme 前缀路由本地 ↔ S3 零代码切换的 Rust 后端
proc-macro crate 做 FromParam deriveRocket + 多 newtype ID 项目
DockerSettings.yaml + Dockerfile.j2 + docker-bake.hcl 三件套需要给多架构(尤其 ARMv6/v7)发布镜像
web-vault digest pinning + 手动升级任何消费上游 container image 的项目
build.rs 把 git tag/commit 编进二进制几乎所有 Rust CLI / server

关键设计决策

  1. 决策:Rocket + Diesel + 自实现 DbConn 桥接

    • 问题:Rocket 是异步框架,Diesel 是同步阻塞 ORM,桥接是非典型需求
    • 方案:run_blocking 包装 + DbConn request guard + semaphore 限流
    • Trade-off:失去 Diesel 原生 async story(Diesel 2.2 async 才出现,Vaultwarden 已定型无法回头),代码复杂度上升
    • 可迁移性:中
  2. 决策:用 bitschema 公开端点路径与 JSON 字段命名强制保持 camelCase

    • 问题:官方 Bitwarden 客户端严格按 endpoint path + JSON field name 校验
    • 方案:#[serde(rename_all = "camelCase")] 全仓统一 + 路由路径常量集中在 api/core/* 每个文件里
    • Trade-off:牺牲了 Rust 习惯的 snake_case 命名一致性,换来与 .NET 官方服务端字节级兼容
    • 可迁移性:中
  3. 决策:Docker 多架构通过声明式三件套(yaml + j2 + bake)

    • 问题:4 架构 × 2 base = 8 个镜像变体,手工 Dockerfile 不可维护
    • 方案:DockerSettings.yaml 是数据(架构列表 / digest / 镜像 tag),Dockerfile.j2 是模板,docker/Makefile 用 Jinja2 渲染成 Dockerfile.debian/.alpine,最后 docker buildx bake 跑 docker-bake.hcl 做并行构建
    • Trade-off:引入 Jinja2 + bake + Makefile 三层间接,每次新增 arch 要改三个文件;但 ARMv6 (RPi Zero) 支持是用户群核心诉求
    • 可迁移性:中
  4. 决策:SUPPORTED_FEATURE_FLAGS 从 Bitwarden 4 个官方仓库手动 sync + 注释锚点

    • 问题:客户端每加一个新 feature flag,服务端不识别就断开
    • 方案:config.rs:1413-1417 列出 4 个 Bitwarden 仓库的 sync 锚点,每加一个 flag 三方合并
    • Trade-off:手动维护成本高,但避免了”自动 sync 突然引入未审计代码”的 supply chain 风险
    • 可迁移性:中

竞品格局与定位

竞品对比矩阵

维度Vaultwarden官方 Bitwarden (self-host)PassboltKeePassXC + SyncthingKeycloak
客户端 UX★★★★★(官方客户端零修改)★★★★★(自己客户端)★★★(桌面扩展尚可)★★★(桌面强,浏览器/移动端弱)★(无密码管理器形态)
自托管 RAM50–100 MB1.5–2 GB+~300 MB0(无服务端)300–600 MB
部署复杂度单 container,1 分钟10+ container,30 分钟起步中等客户端 + 自配同步中等
Enterprise 特性❌ 故意不做(无 SSO/Directory Connect/SCIM)✅ 全套✅ 团队 sharing + OpenPGP❌✅ IAM 全套
安全审计⚠️ 无 Cure53 级别✅ Cure53 定期公开报告⚠️✅ 客户端独立审计✅
商业支持 / SLA❌✅✅❌✅
多设备同步✅ 即时(服务端中介)✅ 即时✅⚠️(需自接 Syncthing/Dropbox)✅
浏览器自动填充✅(官方浏览器扩展直连)✅⚠️⚠️❌

差异化护城河

  • 生态护城河(最强):让 Bitwarden 客户端生态(移动/桌面/浏览器扩展/CLI/1Password importer/家族共享)全免费可用——这是 KeePass/Passbolt/ProtonPass 都打不进去的护城河。客户端兼容性本身才是核心资产,不是 Vaultwarden 代码本身。
  • 技术护城河(弱):任何有时间的 Rust 开发者都能重写(Vaultwarden 已经证明了)。
  • 信任护城河(中):AGPL + 大量用户 + Daniel 受雇于 Bitwarden 这种”半官方”地位带来隐性背书;但缺 Cure53 审计是真硬伤(Reddit 2025-05 两年使用评论明确点出此结构性风险)。

竞争风险

  1. 最危险:官方 Bitwarden 如果某天推出「轻量级 self-host」(比如基于 Bitwarden 的 Rust 重写),Vaultwarden 立刻边缘化——这也是 Daniel 受雇于 Bitwarden 这种暧昧关系既是优势也是定时炸弹的原因(issue #246 评论中已出现”are you going to be replaced by your employer”讨论)。
  2. 次要:Bitwarden 客户端 API breaking change 速率加快(参考 #7607、#4870、#687),Vaultwarden 跟不上节奏会失去「兼容性」核心卖点。
  3. 边缘:Passbolt 个人 UX 改善、KeePassXC 浏览器扩展补强,会蚕食相邻象限,但不会消灭 Vaultwarden 的”Bitwarden 客户端生态中介”身份。

生态定位

「轻量级自托管密码管理器的默认选项」 —— 不挑战官方商业版、不挑战 1Password 商业 SaaS,只占据「官方太重 + KeePass 太本地」之间的甜蜜点。

自托管密码管理赛道中无明显同象限挑战者。

套利机会分析

  • 信息差:零 —— 已是赛道绝对头部(仅次于官方 Bitwarden 客户端生态);价值在「运营效率和设计哲学借鉴」而非”被发现”。
  • 技术借鉴:
    • Rocket + Diesel 桥接:run_blocking + DbConn 自实现归还(任何 Rocket + 同步 ORM 项目)
    • make_config! 声明宏把配置编进类型系统(任何中型 Rust 后端)
    • 多 DB 方言支持:Diesel MultiConnection + 手写 DbConnManager + schema #[cfg] 分支
    • OpenDAL + s3:// scheme 路由做本地/S3 透明切换
    • Docker 多架构矩阵的三件套(yaml + j2 + bake)
    • proc-macro crate 消除 newtype ID 样板代码
  • 生态位:在「Bitwarden 客户端体验 × 自托管 × 极低资源占用」象限是唯一存在 —— KeePass 太本地、Passbolt 偏团队、官方太重。
  • 趋势判断:
    • Vaultwarden 本身已 不在增长高峰(2022-Q4 ~ 117 commit/月的峰值后回落到月均 ~15),但 Bitwarden 客户端生态持续扩张(ProtonPass / 1Password 没在侵蚀),它占据的象限中长期有需求。
    • 后发劣势:任何后来者想做类似项目,必须面对 8.5 年 + 66k★ + 已被 Docker Hub / LinuxServer.io 收录的事实标准壁垒;但Rust 生态今天做这种项目比 2018 年容易得多(actix-web/axum/Rocket 都成熟、Diesel 2.x async 也快了),后发者通过「官方 Bitwarden 客户端兼容 + Cure53 审计 + 价格更低 SaaS」组合有机会。
    • 后发优势:Vaultwarden 的架构债务(Diesel 同步 + Rocket 异步桥接)已成包袱,新项目可以用 sqlx + axum 全部 async 重写一遍。

风险与不足

  • 可持续性风险(最大):官方 Bitwarden 客户端 API 每次大版本(2024.8 / 2026.8…)都会引发一波 break-fix 周期(issue #7607 119 评论、#4870、#687 三连击)—— 这是 Vaultwarden 的结构性「被动追赶」,任何一个客户端 API breaking change 都可能让 Vaultwarden 数周内无法与新客户端配对;随 Bitwarden 加快 release cadence,这种风险会持续加剧。
  • 代码异味:src/api/core/ciphers.rs 单文件 2223 行 + 75 个函数;organizations.rs 3253 行;accounts.rs 1831 行 —— 典型「API 文件作为 god module」模式;api/identity.rs 一个 login 函数 70+ 行处理 6 种 grant_type(line 60–126),内嵌 if-else tree 难以拆解。
  • 过度工程:make_config! 宏本身 + pastey proc-macro + derive_more 5 个 feature 同时开 —— 对 maintainer 是抽象税,对贡献者学习曲线陡。
  • 欠工程 — 测试明显不足:单元测试 #[test] 在 src/ 里仅 ~35 次(http_client.rs 24 个 + storage.rs 4 个 + 其他零星);integration 测试完全没有 src/tests/ 目录;playwright/ 13 个 E2E 文件需要真实 SMTP/SSO 后端;密码学 / 权限检查 / 多 DB 方言一致性测试几乎为零。
  • 安全审计缺失:无 Cure53 级别独立审计报告(Reddit 2025-05 两年使用评论明确点出此为结构性风险)。密码管理器是「存所有用户的最高敏感凭证」的服务,无第三方审计对 66k★ 规模是相对少见的承担。
  • license 风险:AGPL-3.0-only 限制商业二次开发;web-vault 部分是 Bitwarden 官方 AGPL,但 bw_web_builds 仓库有不同 license,混合 license 在分发时需要小心。
  • 架构债务:Diesel + 同步 ORM + Rocket 0.5 异步桥接是历史包袱;今天重写应用 sqlx + axum 全 async,但 Vaultwarden 已定型无法回头。

行动建议

如果你要用它

  • 个人/家庭自托管:✅ 首选 Vaultwarden(docker-compose.yml 一次拉起,SQLite 默认,50–100MB RAM)。比官方栈小 100×,比 KeePass 体验强 10×。
  • 企业/合规需求:❌ 用官方 Bitwarden self-host(Cure53 审计 + 商业支持 + Enterprise SSO/Directory Connect/SCIM 完整)—— Vaultwarden 明确不做企业特性。
  • 多设备同步 + 浏览器自动填充:✅ Vaultwarden;备选 Bitwarden 官方或 1Password。
  • 极简本地优先 / 气隙部署:⚠️ 用 KeePassXC(Vaultwarden 需要服务端,违背 air-gap 场景)。

如果你要学它

按以下顺序阅读源码:

  1. src/main.rs (~500 行):启动期做了哪些事(feature flag 同步 / WebAuthn 迁移 / panic hook / Rocket mount)。
  2. src/config.rs 的 make_config! 块(行 502–937):学习把配置 schema 编进类型系统的极致范例。
  3. src/db/mod.rs:Rocket 异步 + Diesel 同步的桥接、MultiConnection derive 用法、自实现 DbConn 生命周期。
  4. src/storage.rs:OpenDAL 抽象 + scheme 前缀路由的实战。
  5. src/api/core/ciphers.rs:体验单个 API 文件如何变成 god module(2223 行),作为反例思考如何在自己的项目避免。
  6. docker/DockerSettings.yaml + docker/Dockerfile.j2 + docker/docker-bake.hcl:多架构 Docker 矩阵的声明式三件套。
  7. macros/src/lib.rs:proc-macro crate 实战。

如果你要 fork 它

可改进的方向:

  1. 测试覆盖补齐:补单元测试 + integration tests + 多 DB 方言一致性 harness(最值得的改造,PR 会被欢迎)。
  2. 架构 async 化:等 Diesel 2.2 async 稳定后,迁到 sqlx + axum 去掉 run_blocking 桥接的复杂度。
  3. 拆分 god module:把 src/api/core/ciphers.rs / organizations.rs / accounts.rs 按子领域拆分(纯重构、不动行为)。
  4. 加 Cure53 级别审计:找独立安全公司做完整 audit 并公开报告(社区募资+ Bitwarden 资助是可能的路径)。
  5. 加官方 Bitwarden 未实现但用户长期请求的特性:device approval flow、master password re-prompt 策略、可选 enterprise 路径(edge 部署)—— 但需要先解决”会不会被官方母公司挤压”的治理问题。

知识入口

资源链接
DeepWikihttps://deepwiki.com/dani-garcia/vaultwarden
Zread.ai未收录
关联论文无(密码管理器服务端,无学术论文入口)
在线 Demo无(需自部署;上游 Bitwarden 提供 vault.bitwarden.com 试用)
外部独立分析Reddit r/selfhosted 2025-04 Vaultwarden vs Bitwarden Self-hosting — 独立观点:“装完才发现是 Bitwarden 客户端兼容性维护赛跑”。
Reddit r/selfhosted 2025-05 Is Vaultwarden Worth It 2025? — 两年使用诚实话:崩溃/RPi sync 失效/反向代理/ADMIN_TOKEN 持久化 + 无 Cure53 审计风险。

相关报告