Abstract teal and amber illustration of a ledger grid, rising budget chart, and piggy bank shapes with a server silhouette, representing a self-hosted double-entry personal finance manager

Firefly III

Firefly III

Firefly III is a free, self-hosted personal finance manager built around real double-entry bookkeeping, not a simplified expense tracker. It supports budgets, categories, tags, rule-based transactions, and multi-currency accounts, with a REST JSON API covering almost every part of the app. It runs entirely on hardware you control and never contacts external servers unless explicitly told to, the whole pitch for anyone uncomfortable uploading bank statements to a cloud budgeting app.

Quick facts: Firefly III is open source under the GNU Affero General Public License v3 (AGPL-3.0), confirmed from the GitHub repository’s LICENSE file and license badge. Latest stable release is v6.6.3, with over 23,000 stars on GitHub. The official image is fireflyiii/core on Docker Hub, and the project is developed primarily by James Cole (JC5), originating from and based in the European Union.

What is Firefly III?

Most budgeting apps show a running total of what came in and what went out. Firefly III does that too, but underneath it uses double-entry bookkeeping, the same accounting model banks and businesses use: every transaction moves money from one account to another, so nothing just appears or disappears. That makes reconciling accounts and tracking transfers between them far more reliable than a flat list of debits and credits.

On top of that foundation sit the features people stick around for. Budgets can be set per category and period, with automatic rollover. Rules apply tags, categories, or budgets to incoming transactions automatically, so a recurring paycheck doesn’t need manual sorting every month. Piggy banks track savings goals against an account balance, and recurring transactions handle subscriptions and mortgages. A separate companion tool, the Firefly III Data Importer, connects to CSV files, CAMT.05x bank exports, or providers like GoCardless and SimpleFIN to pull transactions in instead of typing them by hand. None of it requires a subscription or an account with the developer; the whole stack lives on the server running it.

How to install Firefly III with Docker

Prereq: Docker and Docker Compose need to already be installed, and you should be comfortable generating random strings for secrets. Our homelab setup guide for beginners covers picking hardware and the Docker basics for a first project.

The official Docker installation docs ship a three-container stack: an app container running Firefly III itself, a db container (MariaDB by default, PostgreSQL supported), and a small cron container that pings Firefly III’s cron endpoint on a schedule for recurring transactions, auto-budgets, and exchange rate updates. That third container is the detail most single-container app guides skip, and it’s why this install rates Medium rather than Easy.

  1. Save the docker-compose.yml below in an empty folder.
  2. Generate a random 32-character string for APP_KEY and another for STATIC_CRON_TOKEN, then replace the placeholders.
  3. Set real database credentials, matching them between the app and db service blocks.
  4. Run the compose file from that folder and open the mapped port to create the first account.
services:
  app:
    image: fireflyiii/core:latest
    container_name: firefly_iii_core
    hostname: app
    restart: unless-stopped
    depends_on:
      - db
    ports:
      - "80:8080"
    environment:
      APP_KEY: "replace_with_32_char_random_string"
      APP_URL: https://firefly.yourdomain.com
      DB_CONNECTION: mysql
      DB_HOST: db
      DB_PORT: 3306
      DB_DATABASE: firefly
      DB_USERNAME: firefly
      DB_PASSWORD: changeme
      STATIC_CRON_TOKEN: "replace_with_32_char_random_string"
      TZ: America/Toronto
    volumes:
      - firefly_iii_upload:/var/www/html/storage/upload

  db:
    image: mariadb:lts
    container_name: firefly_iii_db
    hostname: db
    restart: unless-stopped
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: firefly
      MYSQL_USER: firefly
      MYSQL_PASSWORD: changeme
    volumes:
      - firefly_iii_db:/var/lib/mysql

  cron:
    image: alpine
    container_name: firefly_iii_cron
    restart: unless-stopped
    depends_on:
      - app
    environment:
      TZ: America/Toronto
      STATIC_CRON_TOKEN: "replace_with_32_char_random_string"
    command: ["sh", "-c", "apk add tzdata && echo \"0 3 * * * wget -qO- http://app:8080/api/v1/cron/$STATIC_CRON_TOKEN\" | crontab - && crond -f -L /dev/stdout"]

volumes:
  firefly_iii_upload:
  firefly_iii_db:
docker compose up -d

Warning: APP_KEY and STATIC_CRON_TOKEN must each be exactly 32 characters, or Firefly III will refuse to start correctly. Set the database password before the first run: changing it after the containers have started won’t update it inside the already-initialized database volume, and Firefly III will lose access.

Only port 8080 needs exposing on the app container; the host side of that mapping can be changed to whatever’s free. The cron container is not optional decoration: without it, recurring transactions, bill notifications, and automatic exchange rate updates silently never fire, per the official cron job documentation.

Tip: pin the app image to a specific version tag like fireflyiii/core:version-6.6.3 rather than latest. Firefly III runs database migrations on startup, and an unplanned major-version jump can land mid-migration if a compose stack auto-pulls a new tag on restart.

Automating Firefly III

Compatible with: Firefly III’s REST API and outgoing webhooks mean a self-hosted automation tool can react to new transactions or push data in without touching the database directly.

Since almost every part of Firefly III is exposed through its API, anyone already running n8n can wire it into a broader automation stack: a notification when a budget crosses a threshold, transactions appended to a spreadsheet backup, or a webhook forwarded to a chat app when a large transaction posts. It’s the same glue that makes a homelab feel like one connected system instead of a shelf of separate apps.

Firefly III vs Actual Budget

Actual Budget is the closest self-hosted comparison, and the two aim at different philosophies rather than different feature counts. Actual Budget follows a zero-based, envelope-style budgeting method popularized by YNAB, with a fast local-first sync engine and a lighter single-container Docker setup. Firefly III is built around accounting-grade double-entry bookkeeping and rule automation, with a heavier three-container stack and a steeper learning curve, but far more reporting depth once configured. Neither is “better” outright: Actual Budget suits a fast envelope-budgeting workflow with minimal setup, while Firefly III suits anyone who wants to model where money actually moves between every account they own.

Firefly IIIActual Budget
Core modelDouble-entry bookkeepingEnvelope / zero-based budgeting
Default deploymentThree containers (app + DB + cron)Single container
Bank importSeparate Data Importer (CSV, CAMT, GoCardless, etc.)Built-in bank sync (paid add-on for some providers)
AutomationRules engine, full REST API, webhooksBasic rules, limited API
LicenseAGPL-3.0MIT
  • Real double-entry accounting, not a simplified expense tracker
  • Rules engine automates categorizing and tagging incoming transactions
  • Full REST API and webhooks for building custom automations
  • Supports any currency, with built-in exchange rate tracking
  • Three-container stack (app, database, cron) adds real setup overhead
  • Steeper learning curve than envelope-budgeting apps like Actual Budget
  • Bank import needs a separate Data Importer tool, not built into the core app

FAQ

Is Firefly III free?

Yes. The self-hosted server is fully free and open source under AGPL-3.0, with no paywalled features. The developer accepts donations through Patreon, GitHub Sponsors, and Ko-fi, but none of that is required to run it.

Does Firefly III need a separate database?

Yes. Unlike single-container apps that ship with SQLite, Firefly III requires MySQL/MariaDB or PostgreSQL running as its own service. The official Docker Compose file includes a MariaDB container for exactly this reason.

Can Firefly III import bank transactions automatically?

Not on its own. A separate official tool, the Firefly III Data Importer, handles CSV files, CAMT.05x bank exports, and connections to providers like GoCardless, SimpleFIN, and Enable Banking, then feeds the parsed transactions into Firefly III over its API.

Why does the cron container matter?

Recurring transactions, auto-budgets, subscription/bill warnings, and exchange rate updates only run when something calls Firefly III’s cron endpoint on a schedule. In Docker, that’s the small cron container in the official compose file; skip it and those features quietly never fire.

Is Firefly III good for a household, not just one person?

It supports multiple users and multi-user groups sharing the same financial administration, so a couple or family can track shared accounts under one installation. Permissions are simpler than a dedicated multi-tenant tool, so it works best for a household that trusts each other with full account visibility rather than one needing granular access controls.

Firefly III fits the same “keep sensitive data off someone else’s server” logic behind our self-hosted password manager comparison, just applied to transactions instead of credentials. Financial records are about as sensitive as data gets, and running the manager on hardware already handling other self-hosted services keeps one more piece of a household’s digital life off third-party servers. Our homelab setup guide for beginners covers the Docker fundamentals this install depends on.