SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

自托管记账软件选型:Actual、Firefly III 与 Fava 对比

对比 Actual Budget、Firefly III、Fava 及 Wallos 四款主流自托管记账应用。详细解析各软件的银行数据同步机制、手动导入流程及资源占用情况,助您根据记账习惯选择最适合的方案。

简短回答

自托管预算应用在一点上存在差异,而这一点决定了大多数安装选择:软件是自动获取交易记录,还是需要手动输入。Actual Budget 是家庭预算的首选。它采用信封预算分配法,并以单个容器形式运行。在需要时,它也可以通过银行数据提供商拉取交易记录。

如果您需要复式记账,或者希望在无人值守的情况下按计划自动导入数据,Firefly III 是最佳选择。Beancount 配合 Fava 适合那些希望将账目以纯文本文件形式存储并进行版本控制的用户。Wallos 的功能较为单一:它专门用于追踪每月产生的定期支出。

这些应用本身均无法直接连接银行。所有能够显示银行交易记录的应用,均通过第三方聚合器获取数据,而注册聚合器账户往往是阻碍用户使用的关键步骤。在安装任何应用前,请先阅读同步章节。

各服务的运行方式对比

图表Services, storage and sync model, taken from each project's own install docs
此图表背后的数据
[
  {
    "tool": "Actual Budget",
    "services": 1,
    "storage": "SQLite files",
    "bank_sync": "Aggregators, manual pull",
    "multi_user": "Needs OpenID",
    "encryption": "Optional end to end"
  },
  {
    "tool": "Firefly III",
    "services": 3,
    "storage": "MariaDB",
    "bank_sync": "Importer, cron capable",
    "multi_user": "Built in accounts",
    "encryption": "None at rest"
  },
  {
    "tool": "Beancount + Fava",
    "services": 1,
    "storage": "Text file",
    "bank_sync": "Import scripts only",
    "multi_user": "No login at all",
    "encryption": "File level, your choice"
  },
  {
    "tool": "Wallos",
    "services": 1,
    "storage": "SQLite file",
    "bank_sync": "Manual entry only",
    "multi_user": "Extra logins via admin page",
    "encryption": "None at rest"
  }
]

Actual Budget 运行 1 个常驻服务。Firefly III 运行 3 个,因为其官方 compose 文件将应用、MariaDB 数据库和 cron 辅助程序作为独立容器启动。这就是这 4 个应用的全部资源占用情况:数据库服务器是组内唯一的重负载组件,其余部分仅是占用少量内存的轻量级进程。

哪些自托管预算应用可以从银行拉取交易数据?

没有任何自托管应用能直接连接银行。银行通过开放银行 API 提供交易数据,而这些 API 必须通过聚合器访问:聚合器是持有银行合作关系并转售访问权限的公司。因此,实际问题包含两个方面:该应用是否支持聚合器,以及你是否能获取覆盖你所在银行的聚合器账户?

Actual Budget 支持多种聚合器。截至 2026 年 10 月,其文档列出的支持包括:新西兰的 Akahu、欧洲的 Enable Banking、欧洲的 GoCardless Bank Account Data、北美的 SimpleFIN Bridge 以及巴西的 Pluggy.ai。你需要自行向服务商注册,生成密钥(keys)和机密(secrets),然后将其填入你的服务器。这里有两个限制需要注意。在当前的稳定版本 26.10.0 中,同步操作需手动点击按钮触发。虽然一个按预设间隔自动同步关联账户的设置已被合并,但截至 2026 年 10 月,该功能仅在 nightly 构建版本中提供,且即便在该版本中,同步也仅在设备上打开 Actual 时才会进行。同一页面还指出,GoCardless 不再接受新账户注册,这堵死了旧教程中推荐的免费欧洲同步路径。SimpleFIN Bridge 是一项付费订阅服务,由服务商而非 Actual 向你收费。

如果你希望 Actual 在无人值守的情况下自动导入数据,可以使用一个名为 actual-auto-sync 的社区项目,它能按计划运行银行同步。这是一个与 Actual 服务器并行的独立容器,通过 Actual 的官方 API 包与服务器通信。它不属于 Actual 的一部分,因此你需要额外配置并维护该服务。

Firefly III 将导入功能拆分到了第二个容器中,即 Firefly III Data Importer。其示例配置中包含了 GoCardless (Nordigen)、Enable Banking、SimpleFIN 和 Lunch Flow 的凭据槽位,同时也支持 CSV 和 CAMT.053 文件导入。设置 CAN_POST_AUTOIMPORT=true,在 AUTO_IMPORT_SECRET 中填入一个长随机值,然后在宿主机上设置一个 cron 任务,即可在无需打开浏览器的情况下触发导入。这是本次对比中唯一内置的无人值守同步方案;Actual 必须借助上述额外的社区服务才能实现。

Beancount 没有同步功能。你需要从银行下载 CSV 或 OFX 文件,并运行你自己编写或借用的导入脚本。Wallos 按照设计也没有同步功能:你只需输入一次订阅信息,它就会按设定的周期自动重复。

手动导入是始终有效的方法,且不受银行更换服务商的影响。如果银行连接功能是你选择应用的关键因素,请在安装任何软件之前,先检查聚合器对你所在银行的覆盖情况。这项检查只需十分钟,却能为你节省一个周末的时间。

Actual Budget:基于容器的信封预算管理

信封预算是指在支出前将现有资金分配到特定类别。例如,杂货分配 300,交通分配 80。该方法要求分配总额不得超过账户余额。Actual 不会强制执行此硬性限制:若分配金额超过现有资金,当月将显示为超支,超额部分会从下月资金中扣除,直至补足。Actual 实现了该方法,且该应用优先采用本地模式:浏览器或桌面客户端会保存预算的完整副本并与服务器同步,因此即使服务器宕机,应用仍可正常工作。

services:
  actual_server:
    image: actualbudget/actual-server:latest
    ports:
      - '5006:5006'
    volumes:
      - ./actual-data:/data
    restart: unless-stopped

使用 docker compose up -d 启动该服务。Actual 的 Docker 安装文档建议通过局域网内的其他计算机访问 http://your-server:5006,此时应用在无 HTTPS 的情况下加载。其 HTTPS 页面补充说明,需使用 HTTPS 才能安全使用 Actual 的全部功能,并列出了两种可跳过此步骤的情况:仅通过 localhost 访问的本地计算机服务器,以及为您处理 HTTPS 的云服务提供商。数据卷会生成两个目录:server-files 和 user-files。这两个目录即为您的预算文件。对于通过互联网访问的 VPS,请在首次使用前在前端部署带有 TLS(传输层安全协议)的反向代理,并通过代理提供的 HTTPS 地址访问应用。自签名证书同样有效,但浏览器会提示证书无效。完整操作指南请参考 我们的 Actual Budget 安装指南,该文件背后的 compose 模式请参考 VPS 上的 Docker Compose。

多用户。 默认情况下,服务器仅提供一个共享密码。如需独立账户,需使用 OpenID Connect,服务器支持通过 Authentik、Keycloak、Google 和 GitHub 等提供商进行验证。首位通过 OpenID 登录的用户将成为服务器所有者,ACTUAL_USER_CREATION_MODE 决定后续登录是否自动创建账户。两人可同时打开并编辑同一个预算文件,文档说明该功能可行,除非编辑内容发生冲突。为确保安全,建议避免同时操作同一文件,因此共享同一预算的伴侣应轮流使用。

加密。 Actual 为每个预算文件提供端到端加密。开启后,服务器存储的数据将无法被读取,这正是租用服务器时所需的安全保障。此举有两个后果:若丢失加密密码,服务器副本将无法恢复;唯一的恢复途径是从仍存有预算本地副本的设备重置密钥,这将用该副本覆盖服务器数据。此外,银行同步令牌是单独存储的,不包含在加密范围内,因此任何拥有服务器数据库访问权限的人均可读取这些令牌。

Firefly III:复式记账,以及这里唯一的无人值守导入

复式记账意味着每笔交易都有来源账户和目标账户。购买日用品时,资金会从支票账户转入费用账户,因此不会凭空出现资金。无法解释的资金会表现为账户不平衡,而不是隐藏在分类总额中。这正是选择 Firefly III 的原因:它更接近会计系统,而不是预算工具。

从项目自带的文件安装:

mkdir -p /srv/firefly
curl -fsSL -o /srv/firefly/docker-compose.yml https://raw.githubusercontent.com/firefly-iii/docker/main/docker-compose.yml
curl -fsSL -o /srv/firefly/.env https://raw.githubusercontent.com/firefly-iii/firefly-iii/main/.env.example
curl -fsSL -o /srv/firefly/.db.env https://raw.githubusercontent.com/firefly-iii/docker/main/database.env

首次启动前编辑 .env。APP_KEY 必须是长度恰好为 32 个字符的字符串,项目提供了生成该字符串的命令:

head /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32 && echo

STATIC_CRON_TOKEN 需要另一个长度为 32 个字符的字符串。该 compose 文件中的 cron 容器每天调用一次应用。没有有效令牌时,请求会被拒绝,周期性交易和账单提醒也就不会执行。将 SITE_OWNER 设置为您的电子邮件地址,使 .env 中的数据库密码与 .db.env 中的密码一致,然后启动:

docker compose up -d
docker compose logs -f app

首次启动正常时,应用会在容器内监听端口 8080,compose 文件会将该端口发布到主机的端口 80,日志也会趋于稳定。如果数据库连接错误持续循环出现,说明 .env 和 .db.env 中的密码不一致,因此应用无法登录 MariaDB。

自动导入。 Data Importer 作为独立容器运行,并使用 FIREFLY_III_ACCESS_TOKEN 中的个人访问令牌向 Firefly III 进行身份验证。以交互方式配置一次导入,保存它生成的配置文件,然后让 cron 按计划向自动导入端点发送请求。人们所说的 Firefly III 会同步,指的就是这个过程:聚合器维护银行连接,导入器从聚合器收集数据,而您的服务器会在您休息时完成处理。

多用户。 Firefly III 将真实账户保存在自己的数据库中,AUTHENTICATION_GUARD=web 用于选择此模式。改为指向 remote_user_guard 后,Authelia 等身份验证代理会处理登录,并通过请求头传递用户名。不再支持 LDAP。在可从互联网访问的实例上,首次登录后打开管理页面,检查单用户模式设置。该设置控制其他用户是否可以注册。

加密。 Firefly III 不提供静态数据加密。交易以可读形式存储在 MariaDB 中,因此任何拥有数据库密码或卷副本的人都可以获取您的财务历史。请在其前方终止 TLS,并尽可能避免将其暴露在开放互联网中,同时加密备份。

Beancount 和 Fava:账本即文本文件

Beancount 是一种纯文本复式记账语法。一笔交易就是你所拥有的文件中几行代码:

2026-08-19 * "Supermarket" "Weekly shop"
  Expenses:Food:Groceries   42.10 EUR
  Assets:Bank:Checking

Fava 是该文件的 Web 界面。它负责绘制图表、资产负债表和损益表,并支持编辑源文件。请在虚拟环境中安装它:

sudo apt update && sudo apt install -y python3-venv
python3 -m venv ~/.venvs/fava
~/.venvs/fava/bin/pip install fava
~/.venvs/fava/bin/fava --read-only ~/ledger/main.beancount

在 Ubuntu 24.04 上,直接运行 pip3 install fava 会因为 apt 接管了系统 Python 而导致 error: externally-managed-environment 错误,因此使用虚拟环境是解决问题的根本方案,而非权宜之计。

Fava 默认监听 localhost 的 5000 端口。使用 -H 可以更改主机地址,使用 -p 可以更改端口,但在扩大访问范围前请慎重:Fava 没有登录功能。命令行不提供用户或密码选项,因此任何能访问该端口的人都能读取你所有的交易记录。请保持默认主机设置,并通过 SSH 隧道、VPN 或具备身份验证功能的代理进行访问。--read-only 标志可禁止浏览器写入,当你习惯在笔记本电脑上编辑文件并提交时,建议设置此项。

多用户与加密。 该程序完全没有用户模型。一个实例仅服务于一个账本,且不关联任何身份信息,因此共享意味着共享代理的登录权限。加密方式取决于你对文件采取的措施,例如使用 age 或 gpg 加密副本,或者使用加密的备份仓库。文本账本的优势在于,git 可以免费为你提供历史记录、代码溯源(blame)以及远程备份。

Wallos:用于管理周期性费用的轻量级工具

services:
  wallos:
    image: bellamy/wallos:latest
    ports:
      - "8282:80/tcp"
    volumes:
      - './db:/var/www/html/db'
      - './logos:/var/www/html/images/uploads/logos'
    restart: unless-stopped

Wallos 将所有数据存储在 db/wallos.db 的单个 SQLite 文件中。它支持多种货币及其汇率转换,并可通过电子邮件、Discord、Telegram、Gotify、Pushover 或 Webhook 发送即将续费的提醒。管理员可在管理页面创建额外账户,该页面还支持开启注册功能或启用 OpenID Connect 登录,每个账户拥有独立的列表。在设置中添加的家庭成员仅作为支付方的标签,并非独立的登录账户。

需明确其功能定位。Wallos 不用于追踪日常支出,也没有预算管理功能。它仅解决一个问题:我每月支付哪些费用,以及下周有哪些项目需要续费?许多用户将其与 Actual 配合使用,正是为了实现这一目的。如果你关注的周期性金额是收款而非付款,请参考 自托管发票软件。

Maybe 怎么样?

Maybe Finance 经常在很多讨论中被推荐,因此有必要说明情况。其 README 声明该仓库已不再积极维护,最终版本标记为 v0.6.0,代码采用 AGPLv3 许可证。该仓库已于 27 July 2025 归档为只读。它目前仍可运行。预算数据通常需要保存十年,而让一个持有数据库架构和银行凭据、且已停止维护的软件保存这些数据,并不是可靠的选择。截至 October 2026,情况仍然如此,因此在决定采用前,请自行检查该仓库。

这些服务需要多大的服务器资源?

这些服务都很轻量,建议通过实际测量得出结论,不要盲目相信博客中的数字。在正常使用一天后,在你的服务器上运行以下命令:

docker stats --no-stream

查看 MEM USAGE 列。实际上,Wallos 和 Fava 每个服务仅通过一个小型进程维护一个小型文件,因此它们可以与其他服务轻松共存于一台配置普通的 VPS 上。Firefly III 的情况不同,因为其技术栈中包含 MariaDB,而数据库服务器无论是否在处理查询,都会占用内存。请为数据库预留内存空间,而不是仅考虑交易量。即便如此,预算管理应用通常不会占满 VPS:如果你要为整个技术栈规划服务器,PhotoPrism 和 Immich 的内存底线 才是决定你需要购买多少内存的关键因素。

数据本身几乎不会增长。十年的家庭交易记录文件仅占用几 MB 空间,因此磁盘容量不是瓶颈。这种长期运行带来的真正影响将在下一节讨论。

移动端体验及其局限性

这是自托管财务应用相比商业软件的劣势所在,在将家庭财务迁移至此类平台前,请务必认清现实。

官方文档明确指出其移动端应用已被弃用。取而代之的是网页版,文档将其描述为响应式渐进式 Web 应用(PWA),你可以将其安装到主屏幕并像原生应用一样使用。它运行良好。虽然社区维护着非官方的原生客户端,但它并非应用商店中的原生应用。

Firefly III 也没有官方应用,但其 API 催生了两个功能强大的非官方客户端。Waterfly III 是一款 Android 应用,已在 Google Play 和 F-Droid 上发布。Abacus 支持 iPhone、iPad 和 Android,通过 OAuth2 登录,并将令牌存储在 iOS 钥匙串中。这两者都需要你的实例能从手机端访问。

Fava 和 Wallos 仅提供响应式网页。在手机上查看账本尚可,但使用手机键盘输入 Beancount 交易则非常不便。

所有应用都面临一个共同点:使用移动数据网络的手机并不在你的家庭网络内。你必须将应用发布在配置了 TLS 和强身份验证的域名下,或者通过 VPN 连接。将财务应用发布到公网且仅设置一个共享密码是必须避免的错误。如果这两种方式都不适合你,将实例部署在 v3 onion 服务之后是第三种选择,它无需公网 DNS 记录,也无需向互联网开放端口,代价是需要在手机上通过 Tor Browser 访问。

备份:本类别中最关键的部分

丢失媒体库只需重新下载即可。但丢失五年已分类的交易记录则无法找回。请在第一天就配置好备份。

各应用的备份内容:

  • Actual Budget:整个数据卷,包括 server-files 和 user-files。
  • Firefly III:数据库转储文件,以及 .env、.db.env 和上传目录。
  • Beancount:账本文件,建议作为 git 仓库并配置远程仓库。
  • Wallos:db/wallos.db 和上传的 logo 目录。

直接复制运行中的 SQLite 文件是导致备份无法恢复的常见原因。SQLite 会将最近的写入操作保存在单独的预写日志文件中,因此仅复制 .sqlite 文件可能导致丢失最新交易,甚至无法打开。复制期间请停止容器,只需几秒钟:

cd /srv/actual
docker compose stop actual_server
tar czf /srv/backups/actual-$(date +%F).tgz -C /srv/actual actual-data
docker compose start actual_server

Firefly III 需要数据库转储。请在数据库容器内部执行导出,以防密码泄露到 shell 历史记录中:

cd /srv/firefly
docker compose exec -T db sh -c 'mariadb-dump -u firefly -p"$MYSQL_PASSWORD" firefly' > /srv/backups/firefly-$(date +%F).sql

较旧的 MariaDB 镜像使用其旧名称 mysqldump 提供该工具。请将 .env 和 .db.env 与转储文件存放在一起,因为如果恢复数据库时丢失了对应的配置文件,在紧急情况下将难以处理。

在同一台 VPS 上备份仅能防止误操作。它无法防止服务器丢失或被入侵。请使用 restic 将备份目录推送到对象存储,它会在数据离开服务器前进行加密:

export RESTIC_REPOSITORY=s3:s3.example.com/money-backups
export RESTIC_PASSWORD_FILE=/root/.restic-pass
restic init
restic backup /srv/backups
restic forget --keep-daily 7 --keep-weekly 8 --keep-monthly 12 --prune

restic snapshots 现在应列出带有今日日期的时间戳快照。关于调度、凭据和 systemd 定时器的详细信息,请参阅 VPS 上加密 restic 备份指南。

从未恢复过的备份只是猜测。现在就进行测试,确保一切正常:

restic restore latest --target /tmp/restore-test

将 Actual 的归档文件解压到临时目录,在另一个端口启动第二个容器并打开它。你应该能看到备份时账户的余额。对于 Firefly III,将转储文件加载到临时数据库中,并统计 transactions 表中的行数。如果数字与生产环境一致,说明备份有效。测试完成后删除临时副本,因为遗留带有真实财务数据的测试实例会带来安全隐患。

先选择一个应用,在迁移历史数据前使用真实数据运行一个月,并确保在同一周内完成备份配置。如果你还在考虑哪些生活数据适合自托管,2026 年值得自托管的服务汇总 涵盖了其余的栈。

FAQ

哪款自托管预算应用可以连接我的银行?

Actual Budget 和 Firefly III 都可以,但需要通过第三方聚合服务,而不是直接连接银行。Actual 支持 SimpleFIN Bridge(北美)、Enable Banking(欧洲)、Akahu(新西兰)和 Pluggy.ai(巴西)等服务商。在当前稳定版本中,您需要按下按钮后才会执行同步。截至 2026 年 10 月,只有 nightly 构建支持按指定间隔自动同步,而且仅在 Actual 保持运行时执行;社区服务 actual-auto-sync 可作为额外容器,按计划执行同步。Firefly III 使用独立的 Data Importer 容器,可通过 cron 触发,因此它是唯一内置无人值守导入功能的应用。Beancount 和 Wallos 完全不支持银行连接。选择之前,请确认聚合服务覆盖您的具体银行,因为实际覆盖范围通常比功能更能决定结果。

我可以在手机上使用这些预算应用吗?

可以,但没有官方应用。Actual 的文档说明,官方移动应用已弃用,并推荐使用 Web 版本;这是一个响应式渐进式 Web 应用,您可以将其安装到主屏幕。Firefly III 有两个可靠的非官方客户端:Android 上的 Waterfly III,以及 iOS 和 Android 上的 Abacus。Fava 和 Wallos 只有响应式网页,没有其他客户端。Actual 会在本地保存预算副本,因此没有网络连接时仍可工作,但手机必须能够访问您的服务器,才能同步并获取银行数据。其他应用的所有功能都依赖服务器。无论使用哪种应用,都应配置带 TLS 的域名和强身份验证,或者让手机通过 VPN 访问。

如何备份自托管预算应用,同时避免损坏数据库?

不要单独复制正在使用的 SQLite 文件。SQLite 会将最近的写入保存在单独的预写日志中,因此在写入期间复制文件可能遗漏交易,或导致副本无法打开。停止容器,复制数据目录,然后重新启动容器;这类应用的数据量很小,整个过程只需几秒。对于 Firefly III,请改为在数据库容器中运行 mariadb-dump,并同时保存环境文件和导出文件。将结果加密发送到主机外的 restic 仓库,并至少恢复一次以确认备份可用。

Firefly III 对小型 VPS 来说是否过重?

它是这里最重的选项,唯一原因是其官方 compose 文件会在应用容器和 cron 容器旁边运行 MariaDB 服务器。个人财务数据量很小,因此内存主要消耗在空闲的数据库进程上,而不是交易数据上。在您自己的主机上经过正常使用一天后运行 docker stats --no-stream,读取 MEM USAGE 列,不要直接相信公开发布的数值。如果您需要尽可能小的资源占用,Actual Budget 和 Wallos 都只运行一个进程,并使用一个文件。

#budgeting#personal-finance#自托管#Docker#privacy