【实用的开源工具】ezBookkeeping:轻量的自托管记账应用,还支持 MCP
「实用的开源工具」系列:我只收集值得用的开源项目,写清楚它能做什么、怎么部署、有哪些坑,并在文末标明出处。内容整理自官方文档,核对日期 2026-10-31,具体版本以官方为准。这篇我没有实际部署验证,命令和配置都来自官方文档和仓库;涉及我自己的判断时,会明确标出来。
项目信息卡
| 项目 | 说明 |
|---|---|
| 名称 | ezBookkeeping |
| 做什么 | 自托管的个人记账应用:记流水、查账单、看图表、导入导出数据;可选的 AI 识别和 MCP 接入 |
| 许可证 | MIT |
| 仓库 | github.com/mayswind/ezbookkeeping |
| 官方文档 | ezbookkeeping.mayswind.net(GitHub 仓库的 Website 字段指向它) |
| 最近版本 | v2.1.1(2026-10-23 发布,查询于 2026-10-31);仓库未归档,最近一次推送 2026-10-29 |
| 运行方式 | 单个容器(也可以用二进制),默认端口 8080;容器内数据库文件在 /ezbookkeeping/data,上传的图片在 /ezbookkeeping/storage |
| 数据库 | 支持 SQLite、MySQL、PostgreSQL;官方说明 SQLite 只建议用来测试 |
| 官方没有 | 官方说明不提供托管服务,也没有独立的桌面或手机 App(用浏览器访问,可添加到手机主屏幕) |
它能做什么
- 记账本身:两级账户和两级分类,支持标签、交易图片、定时交易,可以按日期、分类、账户、金额、标签、备注筛选。
- 多币种和多时区:支持多种货币和汇率来源。
- 图表分析:有预置的统计图表,也有可以自定义维度的 Insights Explorer。
- 导入导出:官方列出的导入格式包括 CSV、Excel、OFX、QFX、QIF、GnuCash、Firefly III、Beancount 等;导出为 CSV 或 TSV。
- 安全相关:两步验证(2FA)、OIDC 外部登录、登录失败限速、应用锁(PIN 或 WebAuthn)。
- AI 相关(默认都关闭):文本和小票图片识别记账、AI 生成自定义图表,以及本文重点讲的 MCP。
- 轻量:官方 FAQ 的说法是单用户在 Linux/amd64 上通常只占 40 MiB 左右内存。
不太适合的情况:你需要银行自动同步、或者要原生手机 App。它是个浏览器访问的服务端程序。
部署
先建目录。官方说明容器里的进程用 UID/GID 1000 运行,挂载的目录要让这个用户可读写:
mkdir -p /opt/ezbookkeeping/{data,storage,log} && cd /opt/ezbookkeeping
chown -R 1000:1000 data storage log生成一个随机的 secret_key(官方给的两种方式之一):
openssl rand -base64 32compose.yaml(环境变量名、挂载路径来自官方文档,端口绑定和 restart 是我加的):
services:
ezbookkeeping:
image: mayswind/ezbookkeeping:2.1.1
container_name: ezbookkeeping
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
environment:
- "EBK_SERVER_DOMAIN=ezbookkeeping.example.com"
- "EBK_SERVER_ROOT_URL=https://ezbookkeeping.example.com/"
- "EBK_SECURITY_SECRET_KEY=把上一步生成的随机字符串粘贴到这里"
volumes:
- "./data:/ezbookkeeping/data"
- "./storage:/ezbookkeeping/storage"
- "./log:/ezbookkeeping/log"几点说明:
- 镜像标签:官方文档里镜像是
mayswind/ezbookkeeping(最新发布版)、mayswind/ezbookkeeping:{version}(指定版本)、mayswind/ezbookkeeping:latest-snapshot(每日构建)。我查 Docker Hub 时2.1.1这个标签存在,注意没有v前缀(GitHub 上叫 v2.1.1,Docker Hub 上v2.1.1查不到)。你照抄前请再确认一次标签还在。 secret_key必须在第一次运行前设好。 官方在配置文档里是这么要求的,不能留空上线。- 上面用的是默认的 SQLite,只适合试用。长期用的话,官方建议换 MySQL 或 PostgreSQL,对应的环境变量是
EBK_DATABASE_TYPE(mysql或postgres)、EBK_DATABASE_HOST、EBK_DATABASE_NAME、EBK_DATABASE_USER、EBK_DATABASE_PASSWD。官方的完整示例用的是 MySQL,演示站的 Compose 里用的是 MariaDB。数据库容器本身怎么配,请看你选的数据库的文档,这里不展开。 - 环境变量的命名规则是
EBK_{段名}_{选项名},所有配置文件里的选项都能这样覆盖。
启动:
docker compose up -d
docker compose logs -f ezbookkeeping打开 http://127.0.0.1:8080(远程服务器可以先用 SSH 端口转发看)。
官方也给了不用 Compose 的单行命令,但它没有挂载数据目录,容器一删数据就没了,只适合看一眼界面:
docker run -d -p8080:8080 --name ezbookkeeping mayswind/ezbookkeeping想用二进制部署的话,解压发布包后执行 ./ezbookkeeping server run,同样监听 8080。
Nginx 反向代理
官方文档给了 Nginx 示例,把应用放在域名根路径,核心是下面这几个头:
upstream ezbookkeeping-upstream {
server 127.0.0.1:8080;
}
server {
listen 80;
listen [::]:80;
server_name ezbookkeeping.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name ezbookkeeping.example.com;
# 官方示例没写证书,这两行是我补的
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
location / {
proxy_pass http://ezbookkeeping-upstream;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}要点:
- 官方只在“用户看到的协议或端口,和程序自己监听的不一样”时才要求设置
root_url。上面走 HTTPS 的 443,而程序是 HTTP 的 8080,所以我们在 Compose 里写了EBK_SERVER_ROOT_URL。 - 官方文档也给了放在子路径(例如
/ezbookkeeping)的写法,需要额外的重写规则,并把root_url设成带子路径的地址。我只推荐用单独的子域名,省事。 - 官方的
trusted_proxy_ips默认包含127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16等内网段,只有请求来自这些地址时,程序才会采信X-Forwarded-For之类的头。Nginx 和容器在同一台机器上通常落在这个范围内;如果你的代理在别的网段,要自己加进这个选项。
第一次使用
按官方的“基本使用”文档:
- 没有默认账号。 第一次运行数据库是空的,在注册页创建用户。注册时要选语言、默认货币和一周的第一天,其余本地化设置登录后可以在“用户资料”里改。
- 创建账户。 在“账户”页点“添加”,设置账户类别、名称、初始余额。官方建议让每个账户对应现实里的一个账户(比如一张银行卡)。信用卡和负债账户记录的是欠款,其他账户记录的是余额。
- 创建分类。 注册时可以选择自动创建默认分类,也可以之后在“交易分类”页自己建。分类是两级,记账时必须选二级分类。
- 记一笔。 选类型(支出、收入、转账)、金额、分类、账户和时间,还可以加位置、图片、标签和备注。
- 改余额的方式。 官方的设计是初始余额只能在建账户时设置,之后要调整,需要记一笔收入或支出。对账单页面有“更新期末余额”功能,会自动算出差额并填到新交易里。
用 MCP 接入你的 AI 工具
MCP(Model Context Protocol)让你自己的 AI 工具直接调用 ezBookkeeping:用自然语言记账、查询交易、分析历史数据。
1. 开启。 官方说明默认不启动 MCP 服务,要把配置里的 enable_mcp 设成 true。用环境变量的话,按上面的命名规则就是 EBK_MCP_ENABLE_MCP=true(这个名字是我按官方规则推出来的,官方示例里没有直接写)。在 Compose 的 environment 里加一行,然后重启:
- "EBK_MCP_ENABLE_MCP=true"2. 生成令牌。 MCP 需要一个专用令牌。开启后,桌面版“用户设置 → 安全”页会出现“生成令牌”按钮,点击后输入密码。也可以用命令行:官方命令行文档里有 user-session-new,支持 --type mcp,并要求 --expiresInSeconds(0 表示永不过期)。容器里二进制路径是 /ezbookkeeping/ezbookkeeping(见官方 Dockerfile),所以大致是:
docker compose exec ezbookkeeping /ezbookkeeping/ezbookkeeping user-session-new -n 你的用户名 -t mcp -e 25920002592000 秒是 30 天,是我随手选的示例值,请按需要改。
3. 配到 AI 工具里。 官方给的配置格式如下(type 是 streamable-http),把地址换成你自己的域名,令牌放在 Authorization 头里:
{
"mcpServers": {
"ezbookkeeping-mcp": {
"type": "streamable-http",
"url": "https://ezbookkeeping.example.com/mcp",
"headers": {
"Authorization": "Bearer 你的令牌"
}
}
}
}官方示例里的地址写的是 http://{domain}/mcp,我按反向代理走 HTTPS 改成了 https。
4. 官方列出的 MCP 工具:
| 工具名 | 用途 |
|---|---|
add_transaction | 添加交易,支持 dry_run(只校验不保存) |
query_transactions | 按时间、类型、分类、账户、关键词查询交易,支持分页 |
query_all_accounts | 列出所有账户名 |
query_all_accounts_balance | 列出所有账户余额 |
query_all_transaction_categories | 列出所有分类 |
query_all_transaction_tags | 列出所有标签 |
query_latest_exchange_rates | 查询最新汇率 |
安全提醒(官方文档里有的):
- 官方特别警告:如果你用的是第三方大模型服务,要小心 MCP,你的私人账目数据可能会被发给服务商。
- 如果访问 MCP 的 IP 是固定的(比如家庭网络),可以用
mcp_allowed_remote_ips限制允许的来源 IP,留空表示不限制。 - 令牌能读你的全部账目数据,这是我的判断:把它当密码保管,不用了就撤销(官方命令行有
user-session-list和user-session-revoke)。
另外,官方还提供了 Agent Skill 和命令行脚本工具(让 AI 代理通过 HTTP API 操作),需要先启用 API 令牌,这里不展开,感兴趣看官方文档的 Agent Skill 一页。
更新与卸载
官方 FAQ 的说法:数据库结构向前兼容,升级不会有破坏性改动,也可以随时回滚到旧版本;Docker 部署的话,拉新镜像、重建容器即可。同时官方也建议升级前尽量先用数据库工具备份。
用我们固定了版本号的 Compose,流程是:
cd /opt/ezbookkeeping
# 1. 先备份(SQLite 的话,可以停容器后复制整个 data 目录;用 MySQL/PostgreSQL 就用 mysqldump / pg_dump)
docker compose down
cp -a data data.bak-$(date +%F)
# 2. 把 compose.yaml 里的镜像标签改成新版本(先确认 Docker Hub 上有这个标签),然后:
docker compose pull
docker compose up -d如果你的 image 写的是不带标签的 mayswind/ezbookkeeping,docker compose pull && docker compose up -d 就会拿到最新发布版。
卸载:
cd /opt/ezbookkeeping
docker compose down这只会停掉并删除容器。你的记账数据在 data/ 和 storage/ 目录里,删掉它们就再也找不回来,所以删之前先导出:官方文档里,桌面版“用户设置 → 数据管理 → 导出数据”可以导出 CSV 或 TSV。确认不要了再 rm -rf /opt/ezbookkeeping,镜像用 docker image rm 清理。
踩坑清单
- SQLite 只适合试用。 官方明确建议长期使用换 MySQL 或 PostgreSQL。而且 SQLite 和别的数据库之间互相迁移,要靠第三方工具(官方 FAQ 用 DBeaver 举例),所以最好一开始就想好。
secret_key要在第一次运行前设好。 官方说它用来加密,必须改掉,可以用openssl rand -base64 32生成。这是我的建议:把它和数据一起备份,别随便换。- 一定要挂载持久化目录。 官方说明不挂载的话,容器重建或删除后数据全丢。要同时考虑
/ezbookkeeping/data(SQLite 库)和/ezbookkeeping/storage(头像、交易图片)。用 MySQL 或 PostgreSQL 时,storage仍然需要处理,除非你改用s3、minio或webdav对象存储。 - 挂载目录的权限要给 UID/GID 1000。 否则启动时会报
permission denied。官方 FAQ 明确写了容器里的进程以 1000:1000 运行。 domain和root_url写错,头像、交易图片和邮件里的链接都会出问题。 官方的故障排查页专门讲了这点。有反向代理且协议或端口不一样时,要同时改root_url。- 改了配置要重启。 官方说明配置只在启动时加载。排查时可以看启动日志里输出的生效配置,也可以看浏览器能不能正常加载
/server_settings.js。 - 注册默认是开着的。 配置文档里
enable_register的默认值是true,也就是说任何能打开你网址的人都可以注册。自用的话,建好自己的账号后把它设成false(环境变量按规则是EBK_USER_ENABLE_REGISTER=false,这个变量名是我推出来的)。需要加人时,官方命令行有user-add。 - MCP 默认关闭,开了就要管好令牌和来源 IP。 见上一节;并且别忘了第三方大模型的隐私风险。
- 别把
trusted_proxy_ips想当然。 登录失败限速(默认每个 IP 每分钟 5 次,max_failures_per_ip_per_minute)和 MCP 的来源 IP 限制,都依赖程序读到的真实 IP。真实 IP 只有在请求来自受信任的代理地址时,才会从X-Forwarded-For里取。 - 统计图表会漏掉没有汇率的币种。 官方“基本使用”提示:统计页会把所有金额换算成默认货币,账户币种不在当前汇率数据里的交易会被排除,要选一个覆盖你所有币种的汇率来源。
- AI 识别默认关闭,开启时要想清楚发了什么。 官方 FAQ:文本或图片识别会把粘贴的文本或上传的小票图,连同你全部的分类名、账户名和标签名一起发给你配置的大模型服务;官方建议优先用自托管的模型。
- 导入失败时前端不显示详细原因。 官方说明出于安全考虑,错误详情只写在日志里(默认
log/ezbookkeeping.log),带有出错的行号。 - Docker 发布的端口会绕过 ufw 之类的防火墙。 这是通用的 Docker 知识,不是项目特有的问题,所以我把端口绑定在
127.0.0.1,只让 Nginx 访问。官方示例默认是对所有网卡开放的。 - 升级前先备份,别只靠“向前兼容”。 官方也建议升级前备份数据库,这是个便宜的习惯。
出处
- ezBookkeeping 官方仓库 README(功能、Docker 与二进制安装、许可证)
- 官方文档:Run with Docker
- 官方文档:Configuration(配置项与环境变量规则)
- 官方文档:Reverse proxy configuration
- 官方文档:Basic Usage
- 官方文档:Model Context Protocol
- 官方文档:Command Line
- 官方文档:FAQ(升级、备份、第三方服务与隐私)
- 官方文档:Troubleshooting
- 官方文档:Export & Import
- 官方 Dockerfile(容器内二进制路径、运行用户)
- Docker Hub:mayswind/ezbookkeeping(镜像标签)
- GitHub Releases
有想法或问题?去留言板留言 →