Zum Inhalt

Firefly III per Docker installieren: Eigene Finanzverwaltung für Einnahmen, Ausgaben und Budgets

Veröffentlicht am 28. September 2026 · Geschätzte Lesezeit: 7 Minuten

Firefly III ist eine selbst gehostete persönliche Finanzverwaltung auf Basis der doppelten Buchführung – ähnlich wie klassische Haushaltsbücher, aber digital und automatisiert.[4] Du erfasst Einnahmen und Ausgaben, legst Budgets fest, verwaltest mehrere Konten und Währungen in einer Weboberfläche.[4] Der separate Daten-Importer kann Transaktionen per CSV oder automatisch über GoCardless (Open Banking) von über 6.000 Banken abrufen.[7] Alle Daten bleiben auf deinem eigenen Server. Die Einrichtung dauert etwa 30 Minuten.

Voraussetzungen

  • Ein Linux-Server (Ubuntu 22.04+, Debian 12) mit Docker Engine 24+ und Docker Compose v2
  • Terminalzugriff und ein Benutzer mit sudo-Rechten
  • Ausgehender Internetzugriff zu Docker Hub und GitHub
  • Mindestens 1 GB freier Arbeitsspeicher, 2 GB freier Festplattenplatz

1. Projektordner anlegen und Konfigurationsdateien herunterladen

Erstelle ein neues Verzeichnis für Firefly III und lade die offiziellen Vorlagen herunter:[1][4]

mkdir -p ~/firefly-iii && cd ~/firefly-iii
curl -O https://raw.githubusercontent.com/firefly-iii/docker/main/docker-compose.yml
curl -o .env https://raw.githubusercontent.com/firefly-iii/firefly-iii/main/.env.example
curl -o .db.env https://raw.githubusercontent.com/firefly-iii/docker/main/database.env

Die offizielle docker-compose.yml definiert drei Container: app (Firefly III), db (MariaDB) und cron (Alpine für geplante Aufgaben).[1] Das fireflyiii/core:latest-Image startet einen nginx-Server, der auf Port 8080 lauscht.[1] - .env – die Hauptkonfiguration für Firefly III (Datenbankverbindung, APP_KEY, Zeitzone).[2] - .db.env – Datenbank-Zugangsdaten (getrennt von .env, damit sie nicht versehentlich ins Log gelangen).[3]

2. APP_KEY generieren

Der APP_KEY ist ein genau 32 Zeichen langer Schlüssel, mit dem Firefly III Sitzungen und verschlüsselte Werte schützt. Er muss vor dem ersten Start gesetzt werden und darf später nicht mehr geändert werden.[2] Die offizielle .env-Vorlage empfiehlt die Erzeugung über head /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32.[2]

Generiere den Schlüssel mit folgendem Befehl:

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

Beispiel-Ausgabe: J8aR3kLm9pQ4wX2yZ7bN5cF1vT6gH0sE

APP_KEY nicht nachträglich ändern

Ein nachträglicher Tausch des APP_KEY führt dazu, dass Firefly III gespeicherte verschlüsselte Werte nicht mehr lesen kann. Der Container startet dann mit Fehlern wie The MAC is invalid. Setze den Key nur VOR dem ersten Start.[2]

3. .env-Datei vorbereiten

Öffne die .env-Datei im Projektordner und passe die wichtigsten Werte an:

nano ~/firefly-iii/.env

Setze mindestens diese Werte:

APP_KEY=J8aR3kLm9pQ4wX2yZ7bN5cF1vT6gH0sE
DEFAULT_LANGUAGE=de_DE
TZ=Europe/Berlin
TRUSTED_PROXIES=**
SITE_OWNER=deine@email.de
STATIC_CRON_TOKEN=CHANGE_ME_32_ZEICHEN_TOKEN
  • APP_KEY – der in Schritt 2 generierte 32-Zeichen-Schlüssel.
  • DEFAULT_LANGUAGE=de_DE – Firefly III startet auf Deutsch.[2]
  • TZ=Europe/Berlin – deine Zeitzone. Liste mit timedatectl list-timezones ermitteln.
  • TRUSTED_PROXIES=** – zwingend erforderlich, wenn Firefly III hinter einem Reverse Proxy läuft. Ohne diesen Eintrag erkennt die Anwendung HTTPS nicht und leitet im Kreis weiter.[2]
  • STATIC_CRON_TOKEN – ein zweiter 32-Zeichen-Zufallsschlüssel (am besten ein anderer als APP_KEY). Er erlaubt dem Cron-Container, die geplanten Aufgaben (regelmäßige Buchungen, Budget-Zurücksetzung) zu triggern.[1] Der alpine-Cron-Container ruft täglich um 3:00 Uhr die API auf.[1]

STATIC_CRON_TOKEN muss ebenfalls 32 Zeichen lang sein

Der offizielle Docker-Compose-Cron-Container verwendet diesen Token, um täglich wget -qO- http://app:8080/api/v1/cron/$STATIC_CRON_TOKEN aufzurufen. Ist der Token kürzer oder länger, funktioniert der Cron nicht.[1]

Die Datenbank-Einstellungen in .env sollten schon passen:

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=firefly
DB_USERNAME=firefly
DB_PASSWORD=CHANGE_ME_DB_PASSWORT_1234

4. Datenbank-Passwort setzen

Öffne die .db.env-Datei:

nano ~/firefly-iii/.db.env

Ersetze das Passwort durch ein sicheres:

MYSQL_RANDOM_ROOT_ROOT_PASSWORD=yes
MYSQL_USER=firefly
MYSQL_PASSWORD=<dein-datenbank-passwort>
MYSQL_DATABASE=firefly
  • <dein-datenbank-passwort> – ein sicheres Passwort für den MariaDB-Datenbankbenutzer firefly. Ersetze <dein-datenbank-passwort> durch ein eigenes, sicheres Passwort. Es muss in .env unter DB_PASSWORD und in .db.env unter MYSQL_PASSWORD identisch sein.

Datenbank-Passwort nach dem ersten Start nicht mehr ändern

Das Passwort liegt in der Datenbank-Volume gespeichert. Ein nachträglicher Tausch führt zu Verbindungsfehlern, weil der App-Container das neue Passwort nicht kennt, die Datenbank aber noch das alte erwartet.[3] Ändere das Passwort nur vor dem ersten Start.[3]

5. PostgreSQL verwenden (optional, aber empfohlen)

MariaDB funktioniert stabil, aber PostgreSQL ist unter Firefly III performanter und wird von den Entwickler:innen bevorzugt getestet.[6] Das postgres:16-alpine-Image läuft auch auf ARM64 stabil, während MariaDB lts auf ARM zu Problemen führen kann.[6] Für PostgreSQL ändere in .env:[6]

DB_CONNECTION=pgsql
DB_HOST=db
DB_PORT=5432

Ersetze die .db.env durch PostgreSQL-Variablen:

POSTGRES_USER=firefly
POSTGRES_DB=firefly
POSTGRES_PASSWORD=<dein-datenbank-passwort>

Ersetze <dein-datenbank-passwort> durch dasselbe sichere Passwort wie in Schritt 4.

Und ersetze in der docker-compose.yml den db-Service durch das postgres-Image:[1][6]

  db:
    image: postgres:16-alpine
    hostname: db
    container_name: firefly_iii_db
    restart: always
    environment:
      - POSTGRES_USER=firefly
      - POSTGRES_DATABASE=firefly
      - POSTGRES_PASSWORD=<dein-datenbank-passwort>
    networks:
      - firefly_iii
    volumes:
      - firefly_iii_db:/var/lib/postgresql/data

PostgreSQL 16-alpine auf ARM (Raspberry Pi)

Das postgres:16-alpine-Image läuft auch auf ARM64 stabil. MariaDB lts kann auf ARM zu Problemen führen – dann ist PostgreSQL die sichere Alternative.[6]

6. Port-Konflikt vermeiden

Die offizielle docker-compose.yml bildet Port 80:8080 ab.[1] Port 80 ist oft bereits belegt (z. B. durch einen Reverse Proxy, Nginx oder Caddy). Ändere den Port in der docker-compose.yml auf einen freien Port, zum Beispiel 8080:8080:

    ports:
      - "8080:8080"

Prüfe vorher, ob Port 8080 frei ist:

sudo ss -tlnp | grep 8080

7. Container starten

Prüfe die Konfiguration und starte die Container:[1]

cd ~/firefly-iii
docker compose config --quiet && echo "OK"
docker compose up -d

Der erste Start lädt die Images herunter und führt die Datenbankmigration durch – das kann je nach Internetgeschwindigkeit 2–5 Minuten dauern.[1] Beobachte den Fortschritt:

docker compose logs -f app

Sobald die Logs mit INFO success: nginx entered RUNNING state ... enden, ist Firefly III bereit.[1]

8. Ersten Benutzer anlegen

Rufe http://<deine-server-ip>:8080 im Browser auf. Ersetze <deine-server-ip> durch die IP deines Docker-Servers (z. B. 192.168.1.100). Der erste Aufruf zeigt eine Registrierungsseite. Lege den ersten Administrator-Account an. Nach der Registrierung kannst du direkt loslegen:

  • Konten anlegen (Girokonto, Bargeld, Sparkonto, Kreditkarte)
  • Erste Transaktionen erfassen oder eine CSV importieren
  • Kategorien und Budgets definieren

9. Daten-Importer (optional, für automatischen Bank-Import)

Firefly III kann mit einem separaten Daten-Importer Transaktionen automatisch von deiner Bank abrufen.[7] Der Importer nutzt GoCardless (Open Banking) und unterstützt über 6.000 Banken, darunter viele deutsche Institute.[7]

Installiere den Importer als zweiten Docker-Container nach der offiziellen Firefly-III-Dokumentation.[1][7]

Prüfe vorab, ob deine Bank unterstützt wird: https://gocardless.com/banks/.[7]

Backup/Rückweg

Sichere regelmäßig die Datenbank und die Konfiguration:[1][7]

cd ~/firefly-iii
docker compose exec db sh -c 'mysqldump --user=root --password=$MYSQL_ROOT_PASSWORD firefly' > backup-$(date +%F).sql
cp .env .env-backup-$(date +%F)
cp .db.env .db-env-backup-$(date +%F)

Für den Fall eines Fehlers: docker compose down (ohne -v) stoppt die Container, ohne Daten zu löschen. Mit docker compose down -v werden die Docker-Volumes gelöscht – alle Daten weg.

Typische Fehler

  1. APP_KEY zu kurz oder zu lang: Der Container restartet endlos. Ersetze <key> durch deinen APP_KEY und prüfe: echo -n "<key>" | wc -c muss genau 32 ergeben. Enthält der Key Sonderzeichen (#, <, >), ersetze ihn durch einen rein alphanumerischen.[2]
  2. Port 80 belegt: Der offizielle Compose verwendet Port 80:8080.[1] Wenn Port 80 bereits belegt ist, ersetze ihn wie in Schritt 6 beschrieben.
  3. HTTPS-Weiterleitungsschleife: Setze TRUSTED_PROXIES=** in der .env – sonst erkennt Firefly III hinter einem Reverse Proxy kein HTTPS und leitet im Kreis weiter.[2]
  4. "Connection refused" auf Datenbank: Das depends_on ohne Healthcheck startet den App-Container, bevor MariaDB bereit ist. Die offizielle Compose-Datei hat den Healthcheck integriert, aber bei eigener Konfiguration fehlt er leicht.[1]
  5. ARM/Raspberry Pi: MariaDB (mariadb:lts) läuft auf ARM nicht immer stabil. Verwende PostgreSQL wie in Schritt 5 beschrieben.[6]

Sicherheitshinweise

  • APP_KEY-Verlust = Zugriffsverlust: Notiere den APP_KEY und den STATIC_CRON_TOKEN an einem sicheren Ort (z. B. im Passwort-Tresor). Ohne den APP_KEY sind verschlüsselte Werte unwiederbringlich verloren.[2]
  • Firewall: Setze Firefly III nicht direkt ans Internet. Nutze einen Reverse Proxy mit HTTPS (Traefik, Caddy, Nginx Proxy Manager) oder ein VPN (Tailscale, WireGuard).
  • Regelmäßige Updates: Prüfe regelmäßig auf neue Versionen unter https://github.com/firefly-iii/firefly-iii/releases.[4] Vor jedem Update die Datenbank sichern.
  • Tag statt latest: Die offizielle Compose-Datei nutzt fireflyiii/core:latest.[1] Für mehr Kontrolle pinne auf eine konkrete Version wie fireflyiii/core:version-6.6.6 und aktualisiere bewusst.[7] Die aktuelle stabile Version ist v6.6.6 (Juli 2026).[4]

Fertig

Firefly III läuft und du kannst deine erste Transaktion erfassen. Führe diese Prüfungen durch:

  1. Container laufen: docker compose ps – alle drei Services (app, db, cron) zeigen Up[1]
  2. WebUI erreichbar: curl -s -o /dev/null -w "%{http_code}" http://localhost:8080 → 200 oder 302 (Weiterleitung zur Registrierung)
  3. APP_KEY gültig: docker compose logs app 2>&1 | grep -i "MAC" sollte keine Treffer liefern[2]
  4. Datenbankverbindung: docker compose exec db mysqladmin ping -u root --password=$MYSQL_ROOT_PASSWORD → mysqld is alive[3]
  5. Cron-Test: Ersetze <STATIC_CRON_TOKEN> durch deinen Token und rufe auf: curl -fsS http://localhost:8080/api/v1/cron/<STATIC_CRON_TOKEN> → HTTP 200[1]
  6. Registrierung erfolgreich: Browser öffnen, ersten Account anlegen und eine Testbuchung erfassen

Sources

[1] https://raw.githubusercontent.com/firefly-iii/docker/main/docker-compose.yml — Offizielles Docker-Compose-Manifest [2] https://raw.githubusercontent.com/firefly-iii/firefly-iii/main/.env.example — Offizielle .env-Vorlage [3] https://raw.githubusercontent.com/firefly-iii/docker/main/database.env — Offizielle .db.env-Vorlage (MariaDB) [4] https://github.com/firefly-iii/firefly-iii — Firefly III GitHub-Repository (AGPL-3.0) [6] https://selfhosting.sh/apps/firefly-iii — Selfhosting.sh: How to Self-Host Firefly III [7] https://jacar.es/en/how-to-install-firefly-iii-with-docker — Jacar: How to Install Firefly III with Docker