# ezBookkeeping: a self-hosted personal finance app you run from one Docker command

> ezBookkeeping is a Go and Vue personal finance app for home servers, NAS boxes and Raspberry Pi. It installs with a single Docker command, imports a long list of bank and accounting formats, and trades the polish of commercial apps for data you keep yourself.

**mayswind/ezbookkeeping** — A powerful, lightweight, self-hosted personal finance app that is easy to use.

- Repository: https://github.com/mayswind/ezbookkeeping
- Website: https://ezbookkeeping.mayswind.net
- Stars: 5,687 · Forks: 697
- Language: Go
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/mayswind-ezbookkeeping

## What ezBookkeeping solves, and who ends up running it

Most people who track spending end up choosing between a spreadsheet and a hosted service. The spreadsheet is private and free, but it has no reconciliation, no charts worth looking at and no mobile entry. The hosted service is polished, but your transaction history sits on someone else's disk. ezBookkeeping targets the gap between those two. It is a web application you host yourself, with a mobile-shaped interface and a desktop interface, and it stores your data in a database you control.

The stated audience is narrow and specific: home servers, NAS devices and Raspberry Pi. The README describes the app as resource-efficient and says it runs smoothly on those machines. That is a different claim from "runs anywhere", and it matters. If you already run a container host for other services, adding ezBookkeeping is a small marginal cost. If you have never run a server, the project will still ask you to mount a volume, choose a database and think about backups.

The feature list points at people with more than one account and more than one currency. Two-level accounts and categories, scheduled transactions, image attachments, location tracking on maps, and multiple exchange rate sources with automatic updates are all things a single checking account does not need. The import list is the giveaway: OFX, QFX, QIF, IIF, Camt.052, Camt.053, MT940, GnuCash, Firefly III and Beancount. Those are formats produced by banks and by other accounting tools, which means the intended user is migrating from something, not starting from zero.

## How the Go backend and the Vue frontend fit together

The repository is a two-part application in one tree. The Go module is github.com/mayswind/ezbookkeeping, built with Go 1.27.1, and it depends on gin for HTTP routing, xorm for database access, gocron for scheduled jobs, and the OTP, OIDC and JWT libraries that back the security features. The frontend is a Vue 3 application built with Vite, using Framework7 and Vuetify for the interface, ECharts for charts and Monaco for the script editor.

The Dockerfile shows the two halves being built separately and then combined. A golang:1.27.1-alpine stage runs ./build.sh backend, a node:26.8.1-alpine stage runs ./build.sh frontend, and the final alpine:3.24.1 image copies the compiled binary and the built assets. The runtime image creates three directories owned by uid 1000: /ezbookkeeping/data, /ezbookkeeping/log and /ezbookkeeping/storage. That layout tells you what state the container expects to persist. The data directory holds the database when you use the default embedded engine, the log directory holds application logs, and the storage directory is where attachments and similar files go.

Persistence is the part the README stresses hardest. It states that for production use you need to mount a persistent volume when starting the container to prevent data loss. The one-line docker run example does not do that. It is a quick look, not a deployment. Anyone who runs it as written and then recreates the container loses the ledger.

On the database side, the project supports SQLite, MySQL and PostgreSQL, which is a wider range than most self-hosted apps of this size. SQLite keeps the whole thing in one file and suits a single user on a NAS. MySQL or PostgreSQL makes sense if the host already runs a database server and you want the ledger in a place your existing backup tooling already covers. xorm sits between the application and all three, so the choice is a configuration decision rather than a code path.

## Installing ezBookkeeping with Docker and recording a first transaction

The README's installation section gives Docker as the shortest path and points to Docker Hub for all images and tags. The latest release starts with a single command, publishing port 8080 on the host.

```bash
docker run -p8080:8080 mayswind/ezbookkeeping
```

After that, visit http://{YOUR_HOST_ADDRESS}:8080/ from a browser on the same network. The README says the application listens on port 8080 by default. You should see the login screen, and the first account you create becomes your own.

That command is fine for a first look, but it stores everything inside the container. The README is explicit that production use requires a persistent volume. The Dockerfile creates /ezbookkeeping/data, /ezbookkeeping/log and /ezbookkeeping/storage, so those are the paths to mount. The exact docker run invocation with volume flags is not given in the README; it defers to the Docker installation page at ezbookkeeping.mayswind.net/installation/installation-docker for that.

If you would rather not use Docker, the project publishes binaries on its releases page. On Linux or macOS you unpack the release and start the server:

```bash
./ezbookkeeping server run
```

On Windows the equivalent is:

```bash
.\ezbookkeeping.exe server run
```

Once you are logged in, the first real task is recording a transaction. The README describes two-level accounts and categories, so the flow is to create an account (a bank account, a cash wallet, a credit card), then create categories, then record a transaction against both. After a few entries, the built-in charts start to show something. The overview layout is customizable, which means the default dashboard is a starting point rather than a fixed screen.

The second task worth doing early is an import. If you have a CSV or Excel export from a bank, the README mentions custom column mapping, rules and scripts for those two formats. That is the mechanism that makes a migration practical: you map the columns once, and the rules handle the repetitive parts. The other supported formats (OFX, QFX, QIF, IIF, Camt.052, Camt.053, MT940, GnuCash, Firefly III, Beancount) are recognized directly, so a Firefly III or Beancount export is the easiest way in.

## Where ezBookkeeping is the wrong tool

The AI features deserve a plain reading. The README lists text and receipt image recognition, MCP for AI integration, and agent skill plus API command-line script tools. Those features imply a model or a service somewhere. The README does not describe which provider, whether anything leaves your server, or what happens when the service is unavailable. If your reason for self-hosting is that no third party ever sees your transactions, you should confirm the data flow before enabling receipt recognition, rather than assuming the local-first framing covers it.

The interface is the second trade-off. Framework7 and Vuetify are both general-purpose UI frameworks, and the project maintains separate mobile and desktop layouts. The result is a web app that behaves like an app on a phone, not a native Android or iOS client. PWA support means you can add it to your home screen, and the README links a short animation showing that. It does not mean an installable app from a store, offline reconciliation, or background sync. If you want to enter a transaction on a plane with no connection, this is not that.

Backups are the third. The README tells you to mount a volume and stop there. It does not document a backup command, a restore procedure, or a rollback path between versions. For a ledger you intend to keep for years, that gap is the one to close yourself before you commit real data. The database choice interacts with this: a SQLite file is easy to copy, while MySQL or PostgreSQL hands the problem to whatever you already use for those servers.

Finally, single-user is the safe assumption. The README describes 2FA, OIDC external authentication, login rate limiting and an application lock with PIN code or WebAuthn. Those are protections for an account, and OIDC suggests the project expects to sit behind an existing identity provider. Nothing in the README describes shared ledgers, per-user permissions or household splitting. If two people need to record into the same books with different access, verify that before migrating.

## ezBookkeeping against Firefly III and Actual Budget

Firefly III is the comparison people search for, and the two projects sit close together. Firefly III is a PHP application built on Laravel, typically deployed as a container alongside its own database, and it has a long-standing reputation for depth: double-entry-style bookkeeping, rules engines, budgets and reporting. ezBookkeeping is a single Go binary with an embedded frontend, and it can run on SQLite without a separate database container at all. That is the practical difference. On a Raspberry Pi or a small NAS, one container and one file is a lighter footprint than a PHP stack plus a database server.

The import list makes the relationship concrete rather than tribal. ezBookkeeping can import a Firefly III export, which means the migration path exists in one direction and is documented in the feature list. If you are already running Firefly III and it works, the reason to move is resource usage or operational simplicity, not features.

Actual Budget takes a different approach again. It is built around local-first sync and envelope budgeting, where the mental model is assigning money to categories before you spend it. ezBookkeeping's model, as described in the README, is transaction recording plus analysis: accounts, categories, filters, charts, custom query dimensions. If you want envelope budgeting as the primary workflow, the two tools are answering different questions, and importing your history will not change that.

## Maintenance, upgrades and the MIT licence

The repository is not archived, and the last push was on 2026-09-10. Releases have been frequent: v1.5.1 on 2026-05-31, v1.6.0 on 2026-07-19, and v1.6.1 on 2026-07-20. The Docker Hub page carries both a release tag and a latest-snapshot tag, and the README shows the snapshot image as mayswind/ezbookkeeping:latest-snapshot. Using the snapshot tag means tracking unreleased code. On a ledger, pin the release tag instead.

Upgrade cost is mostly the data layer. The README does not document a migration procedure, a schema version check, or a downgrade path, and it does not describe what happens if you run an older binary against a database that a newer version has already touched. The safe sequence is to copy the data directory before pulling a new image. If you chose SQLite, that is one file in /ezbookkeeping/data. If you chose MySQL or PostgreSQL, it is a dump through the tools you already use for that server.

The licence is MIT, stated in the README badge and in package.json. MIT is permissive: you can run it, modify it and redistribute it, with the copyright notice and licence text preserved. That is the extent of what the repository states, and it is not legal advice. If you plan to redistribute a modified build, read the LICENSE file in the repository root rather than the badge.

Building from source is possible and documented. The README requires Golang, GCC, Node.js and NPM, then ./build.sh package -o ezbookkeeping.tar.gz on Linux or macOS, or .\build.bat package -o ezbookkeeping.zip on Windows. A Docker image can be built with ./build.sh docker. The Dockerfile adds git, gcc, g++ and libc-dev to the Go build stage, which is consistent with the GCC requirement in the README.

## Conclusion

Adopt ezBookkeeping if you already run a container host and want your transaction history in a database you control, especially if you need to import from OFX, QIF, MT940, Firefly III or Beancount and want one container instead of a PHP stack plus a database. Skip it if you need a native mobile app with offline entry, or if you want envelope budgeting as the core workflow, which is a different model. Before entering real data, verify three things: the exact volume mount for /ezbookkeeping/data, /ezbookkeeping/log and /ezbookkeeping/storage as described on the Docker installation page, whether the AI receipt and text recognition sends anything off your server, and how you will restore a backup, since the README documents no restore or rollback procedure.

## FAQ

### What is the best free personal bookkeeping software?

ezBookkeeping is free and open source under the MIT licence, and it is one option among several self-hosted tools. Whether it is best depends on your constraints: it runs as a single Docker container on a home server, NAS or Raspberry Pi and supports SQLite, MySQL and PostgreSQL, which suits people who want low resource usage and their own database. It does not offer a native mobile app, so if offline phone entry is a requirement, look elsewhere.

### How does ezBookkeeping work?

It is a Go backend and a Vue frontend packaged into one container. The backend uses gin for HTTP and xorm for database access, and the Dockerfile builds the Go binary and the Vite frontend in separate stages before copying both into an alpine image. The runtime image expects persistent state in /ezbookkeeping/data, /ezbookkeeping/log and /ezbookkeeping/storage.

### ezBookkeeping vs Firefly III: what is the difference?

Firefly III is a PHP application that typically runs alongside its own database container, while ezBookkeeping is a single Go binary with an embedded frontend that can run on SQLite with no separate database server. ezBookkeeping also lists Firefly III among its supported import formats, so moving from Firefly III to ezBookkeeping is a documented path. The main reason to switch is resource usage and operational simplicity, not feature coverage.

### ezBookkeeping vs Actual Budget: which should I pick?

The two tools model money differently. Actual Budget is built around envelope budgeting, where you assign money to categories before spending. ezBookkeeping, based on its README, centers on recording transactions and then analyzing them with filters, charts and custom query dimensions. Pick based on which workflow you actually want, because importing your history will not change the underlying model.

### Is there an ezBookkeeping alternative I should consider?

Firefly III and Actual Budget are the two alternatives the project itself invites comparison with, since it can import a Firefly III export and both are self-hosted. Firefly III is a heavier PHP and database stack with deep bookkeeping features, and Actual Budget is a local-first envelope budgeting tool. ezBookkeeping's distinguishing point is a single container that runs on SQLite.

## Sources

- [License: MIT](https://github.com/mayswind/ezbookkeeping/blob/main/LICENSE)
- [mayswind/ezbookkeeping on GitHub](https://github.com/mayswind/ezbookkeeping)
- [Project website](https://ezbookkeeping.mayswind.net)
- [README](https://github.com/mayswind/ezbookkeeping/blob/main/README.md)
- [Releases](https://github.com/mayswind/ezbookkeeping/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mayswind-ezbookkeeping
