Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung IT-Branche 06.08.2026 · 10 min Lesezeit

Actual Budget mit Docker installieren: Lokale Budgetverwaltung nach dem Envelope-Prinzip

Actual Budget ist die beliebteste Open-Source-Alternative zu YNAB mit über 27.000 GitHub-Stars. Diese Anleitung zeigt, wie du den Budgetserver in unter 10 Minuten per Docker Compose aufstellst – datenschutzkonform, ohne Cloud-Abhängigkeit, mit SQLite und optionaler Geräte-Synchronisation.

Illustration zur Installation von Actual Budget mit Docker. Die Grafik zeigt eine lokale Budgetverwaltung nach dem Envelope Prinzip mit Docker Container, Weboberfläche, Budget Umschlägen, Finanz Dashboard, Datenbank und Terminal. Ideal als Titelbild für e KI-generiert

Wer seine Haushaltsfinanzen nach dem Umschlag-Prinzip (Envelope-Methode) verwalten möchte, ohne seine Kontodaten in die Cloud zu schicken, hat mit Actual Budget eine ernstzunehmende Option. Die Node.js-Anwendung läuft als einzelner Container, speichert alle Daten lokal in SQLite und ermöglicht die Synchronisation zwischen Desktop, Browser und mobilen Apps über den eigenen Server – ganz ohne externe Datenbankdienste. Mit über 27.000 GitHub-Stars ist Actual Budget die meistgenutzte Open-Source-Alternative zu YNAB im Self-Hosting-Bereich.

Voraussetzungen

  1. Docker Engine ≥ 20.10 und das Docker Compose Plugin v2 (docker compose, nicht das veraltete docker-compose) auf einem Linux-Host, einer VM oder einem NAS mit Docker-Unterstützung. Falls du Docker noch nicht installiert hast, hilft dir die Anleitung Docker und Docker Compose auf Linux installieren weiter.
  2. Mindestens 512 MB RAM frei (empfohlen: 1 GB), mindestens 1 GB freier Speicherplatz für Image und Daten.
  3. Netzwerkzugang für den einmaligen docker pull-Vorgang.
  4. Für HTTPS und öffentlichen Zugriff: ein vorgelagerter Reverse Proxy (nginx, Traefik, Caddy) und ein gültiges TLS-Zertifikat. Caddy mit automatischem HTTPS wird in der Anleitung Caddy als Reverse Proxy einrichten erklärt.
  5. Ein Texteditor sowie Terminal-Zugang zum Host.

Eckdaten auf einen Blick

EigenschaftWert
Primäres Image (Docker Hub)docker.io/actualbudget/actual-server:latest
Alternatives Image (GHCR)ghcr.io/actualbudget/actual:latest
Alpine-Variante (~60 MB)actualbudget/actual-server:latest-alpine
Port5006 (HTTP, konfigurierbar)
Pflicht-Volume./actual-data:/data
DatenbankSQLite (eingebettet, kein externer Container)
Container-User (UID)actual (UID 1001)
Architekturenamd64, arm64, arm/v7 (arm/v6 nur Alpine)
Passwort beim SetupWird beim ersten Browser-Aufruf interaktiv gesetzt

Schritt 1: Projektordner anlegen und Verzeichnisrechte setzen

Lege einen dedizierten Ordner für Actual Budget an. Alle Konfigurationsdateien und das persistente Datenverzeichnis leben dort:

mkdir -p /opt/actual-budget/actual-data
cd /opt/actual-budget

Actual Budget läuft im Container als Benutzer actual mit UID 1001. Das Datenverzeichnis auf dem Host muss für diesen Benutzer schreibbar sein – sonst schlägt der Container beim ersten Schreiben in die SQLite-Datenbank fehl:

chown -R 1001:1001 /opt/actual-budget/actual-data

Auf manchen Systemen (z. B. einem NAS ohne einfachen chown-Zugriff) kannst du alternativ chmod -R 777 /opt/actual-budget/actual-data nutzen, was jedoch weniger restriktiv ist.

Verifizieren: Prüfe Existenz und Besitzer des Ordners:

ls -la /opt/actual-budget/
# Erwartete Ausgabe (Ausschnitt):
# drwxr-xr-x  2 1001 1001  ... actual-data

Schritt 2: compose.yaml erstellen

Erstelle im Projektordner die Datei compose.yaml. Der Stack besteht aus einem einzigen Dienst – kein separater Datenbankcontainer wird benötigt, da SQLite direkt im Image eingebettet ist:

services:
  actual_server:
    image: docker.io/actualbudget/actual-server:latest
    container_name: actual_budget
    restart: unless-stopped
    ports:
      - "5006:5006"
    volumes:
      - ./actual-data:/data
    environment:
      # Port des Servers (Standard: 5006)
      - ACTUAL_PORT=5006
      # Bind-Adresse: :: = IPv4 und IPv6 (Standard)
      # - ACTUAL_HOSTNAME=::
      # Direktes HTTPS (alternativ: Reverse Proxy vorschalten)
      # - ACTUAL_HTTPS_KEY=/data/certs/privkey.pem
      # - ACTUAL_HTTPS_CERT=/data/certs/fullchain.pem
      # Upload-Limits (optional, in MB)
      # - ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB=20
      # - ACTUAL_UPLOAD_FILE_SIZE_LIMIT_MB=20
    healthcheck:
      test: ["CMD", "node", "scripts/health-check.js"]
      interval: 60s
      timeout: 10s
      retries: 3
      start_period: 20s

# Kein externer DB-Container nötig – Actual nutzt eingebettetes SQLite.
# Das Verzeichnis ./actual-data muss für UID 1001 schreibbar sein (siehe Schritt 1).
# Beim ersten Browser-Aufruf erscheint ein Dialog zur Passwortvergabe (Bootstrap).

Hinweis zum Image-Tag: latest verweist immer auf den aktuellen stabilen Stand. Für ressourcenschwache Geräte (Raspberry Pi, ältere NAS-Systeme) empfiehlt sich latest-alpine – funktional identisch, aber nur rund 60 MB groß und als einzige Variante auch für arm/v6 verfügbar. Das nightly-Tag enthält den neuesten Entwicklungsstand und sollte nicht in produktiven Umgebungen eingesetzt werden.

Zwei offizielle Registries stehen zur Verfügung: Docker Hub (actualbudget/actual-server) und die GitHub Container Registry (ghcr.io/actualbudget/actual). Beide Images sind inhaltlich identisch; die Anleitung nutzt Docker Hub als primäre Quelle.

Verifizieren: Prüfe die YAML-Syntax, bevor du den Container startest:

docker compose config
# Erwartet: fehlerfreie Ausgabe der Konfiguration ohne Warnungen

Schritt 3: Container starten

Starte den Stack im Hintergrund. Docker lädt das Image beim ersten Aufruf automatisch herunter:

docker compose up -d

Der Download des Images dauert je nach Verbindung ein bis zwei Minuten (Standard-Image ~150 MB, Alpine ~60 MB).

Verifizieren: Prüfe Status und Gesundheitszustand des Containers:

docker compose ps
# Erwartete Ausgabe:
# NAME            IMAGE                                    STATUS
# actual_budget   actualbudget/actual-server:latest        Up (healthy)

docker compose logs actual_server --tail 20
# Erwartete Ausgabe (Ausschnitt):
# Listening on http://[::]:5006
# Server started successfully

Erscheint statt healthy zunächst starting, warte die im Healthcheck definierte start_period von 20 Sekunden ab und führe docker compose ps erneut aus.

Schritt 4: Erst-Einrichtung im Browser

Öffne in einem Browser auf dem Server-Host oder im lokalen Netzwerk:

http://localhost:5006
# oder vom LAN aus:
http://<SERVER-IP>:5006

Beim allerersten Aufruf zeigt Actual Budget einen Bootstrap-Dialog, in dem du ein Passwort für den Server vergibst. Dieses Passwort schützt alle Budgetdateien auf dem Server. Es gibt kein vorkonfiguriertes Standardpasswort – das Setzen dieses Passworts ist ein Pflichtschritt.

Nach dem Setzen des Passworts kannst du entweder ein neues Budget anlegen oder eine vorhandene Actual-Budget-Datei importieren. Die Benutzeroberfläche ist vollständig in Englisch; eine offizielle deutsche Lokalisierung existiert zum Zeitpunkt dieser Anleitung nicht, die Bedienung ist jedoch auch ohne Vorkenntnisse intuitiv.

Wichtig: Wenn du das Passwort vergessen hast oder einen Neustart des Bootstrap-Prozesses benötigst, lösche ausschließlich die Datei /opt/actual-budget/actual-data/server-files/account.sqlite – die Budget-Dateien in user-files/ bleiben dabei erhalten.

Verifizieren: Teste die HTTP-Erreichbarkeit per curl:

curl -I http://localhost:5006
# Erwartete Ausgabe:
# HTTP/1.1 200 OK  (oder 302 Found mit Location-Header zum Login)

Schritt 5: Datenpfade und Backup verstehen

Actual Budget legt im Volume ./actual-data automatisch zwei Unterverzeichnisse an:

Pfad im VolumeInhalt
server-files/SQLite-Datenbank (account.sqlite), Session-Daten, Server-Konfiguration
user-files/Individuelle Budget-Dateien aller angelegten Budgets

Ein vollständiges Backup ist denkbar einfach – der gesamte actual-data-Ordner enthält alle relevanten Daten:

tar czf actual-backup-$(date +%Y%m%d).tar.gz /opt/actual-budget/actual-data
# Ergebnis: actual-backup-20260612.tar.gz

Für eine automatisierte Backup-Strategie empfiehlt sich die Anleitung Restic Backup auf Linux einrichten und automatisieren. Zusätzlich bietet das Web-UI unter „Einstellungen" eine integrierte Export-Funktion, die einzelne Budgets als Datei exportiert.

Verifizieren: Prüfe, ob die Unterverzeichnisse nach dem ersten Browser-Aufruf vorhanden sind:

ls -la /opt/actual-budget/actual-data/
# Erwartete Ausgabe:
# drwxr-xr-x  ... server-files
# drwxr-xr-x  ... user-files

Schritt 6: Umgebungsvariablen und optionale Konfiguration

Actual Budget benötigt für einen Standardbetrieb keine zwingenden Umgebungsvariablen – alle Einstellungen haben sinnvolle Standardwerte. Die folgende Tabelle listet die wichtigsten konfigurierbaren Parameter:

VariableStandardBeschreibung
ACTUAL_PORT5006Listener-Port des Servers im Container
ACTUAL_HOSTNAME::Bind-Adresse (:: = IPv4 + IPv6)
ACTUAL_DATA_DIR/dataBasispfad für alle Daten im Container
ACTUAL_SERVER_FILES/data/server-filesPfad für SQLite-DB und Sessions
ACTUAL_USER_FILES/data/user-filesPfad für Budget-Dateien
ACTUAL_LOGIN_METHODpasswordAuth-Methode: password, header oder openid
ACTUAL_HTTPS_KEYPfad zum TLS-Schlüssel (direktes HTTPS)
ACTUAL_HTTPS_CERTPfad zum TLS-Zertifikat (direktes HTTPS)
ACTUAL_TRUSTED_PROXIESRFC-1918-internVertrauenswürdige Proxy-IP-Bereiche
ACTUAL_UPLOAD_FILE_SIZE_LIMIT_MBMaximale Upload-Dateigröße in MB

Hinweis zu SECRET_KEY: Verschiedene inoffizielle Anleitungen erwähnen eine SECRET_KEY-Variable. Die offizielle Dokumentation kennt diese Variable nicht – Actual Budget benötigt für den Grundbetrieb kein separates Secret. Das Serverpasswort wird ausschließlich beim ersten Browser-Aufruf gesetzt.

Wenn du sensible Variablen (z. B. zukünftige OpenID-Credentials) aus der compose.yaml heraushalten möchtest, kannst du sie in eine .env-Datei im selben Ordner auslagern:

# /opt/actual-budget/.env
ACTUAL_PORT=5006
# ACTUAL_LOGIN_METHOD=openid

Docker Compose liest .env im Projektverzeichnis automatisch ein. Details zur Compose-Syntax findest du in der Grundlagenanleitung Docker Compose: Multi-Container-Stacks aufbauen.

Verifizieren: Nach Änderungen an der Konfiguration den Container neu starten und Logs prüfen:

docker compose up -d
docker compose logs actual_server --tail 10
# Erwartet: Keine Fehler, „Listening on http://[::]:5006"

Schritt 7: Updates und Wartung

Da alle Daten im Volume ./actual-data liegen und nicht im Container, ist ein Update ohne Datenverlust möglich. Erstelle vor jedem Update sicherheitshalber ein Backup (siehe Schritt 5):

# Optional: Backup vor dem Update
tar czf actual-backup-pre-update.tar.gz /opt/actual-budget/actual-data

# Update durchführen
docker compose pull
docker compose up -d

# Status nach dem Update prüfen
docker compose ps

Docker Compose lädt das neue Image herunter, stoppt den laufenden Container, ersetzt ihn und startet ihn neu. Die Ausfallzeit beträgt typischerweise wenige Sekunden.

Zum Stoppen des Dienstes (z. B. für Wartungsarbeiten):

docker compose down
# Container wird gestoppt und entfernt; Volume ./actual-data bleibt erhalten

Verifizieren: Nach dem Update prüfen, ob der Container mit dem neuen Image läuft:

docker compose ps
docker inspect actual_budget | grep -i image
# Erwartet: neues Image-Digest in der Ausgabe

Troubleshooting / Typische Fehler

  1. EACCES: permission denied, open '/data/server-files/account.sqlite' – Das Volume-Verzeichnis ist nicht für UID 1001 schreibbar. Lösung: chown -R 1001:1001 /opt/actual-budget/actual-data ausführen und den Container mit docker compose restart neu starten.
  2. Bind for 0.0.0.0:5006 failed: port is already allocated – Port 5006 ist durch einen anderen Prozess belegt. Lösung: In der compose.yaml den äußeren Port ändern, z. B. "5007:5006", und docker compose up -d erneut ausführen.
  3. exec format error beim Container-Start auf Raspberry Pi (arm/v6) – Das latest-Tag unterstützt arm/v6 nicht. Lösung: Image-Tag in der compose.yaml auf latest-alpine ändern; nur Alpine-Images unterstützen arm/v6.
  4. Bootstrap-Dialog erscheint nicht mehr, Passwort vergessen – Die Datei /opt/actual-budget/actual-data/server-files/account.sqlite löschen und docker compose restart ausführen. Budget-Dateien in user-files/ bleiben dabei erhalten.
  5. Alle Daten nach Container-Neustart verschwunden – Das Volume wurde nicht korrekt eingebunden. Prüfe, ob der volumes-Eintrag in der compose.yaml vorhanden ist und ob das Verzeichnis ./actual-data korrekt angelegt wurde. docker compose config zeigt den aufgelösten absoluten Pfad.
  6. Mobile App verbindet sich nicht – Die Actual-App (iOS/Android) benötigt die vollständige Server-URL inklusive Port, z. B. http://192.168.1.100:5006 im LAN. localhost ist vom Mobilgerät aus nicht erreichbar. Zusätzlich muss Port 5006 in der Host-Firewall für das lokale Netzwerk freigegeben sein.
  7. Container bleibt im Status „starting" und wird nicht „healthy" – Der Healthcheck benötigt bis zu 20 Sekunden Anlaufzeit. Prüfe mit docker compose logs actual_server, ob Fehlermeldungen erscheinen. Häufige Ursache: fehlerhafte Volume-Rechte.
  8. ACTUAL_HTTPS_KEY/CERT schlagen fehl – Die Pfade müssen auf Dateien innerhalb des Containers zeigen (z. B. /data/certs/privkey.pem). Die Zertifikatsdateien müssen via Volume in das /data-Verzeichnis eingebunden werden.

Häufige Fragen

Brauche ich PostgreSQL oder MySQL für Actual Budget?

Nein. Actual Budget nutzt SQLite als eingebettete Datenbank direkt im Container. Es ist kein zweiter Datenbankcontainer notwendig – das unterscheidet den Stack angenehm von vielen anderen Self-Hosting-Projekten und hält die Komplexität niedrig.

Welches Image-Tag ist für den Dauerbetrieb empfohlen?

Für stabile Produktivsysteme empfehle ich latest oder – besonders auf schwächerer Hardware und ARM-Geräten – latest-alpine. Das Alpine-Image ist funktional identisch, aber deutlich kleiner (~60 MB statt ~150 MB) und unterstützt zusätzlich arm/v6. Das nightly-Tag enthält den neuesten Entwicklungsstand und eignet sich ausschließlich zum Testen neuer Funktionen.

Wie verbinde ich die mobile App mit meinem Server?

Öffne die offizielle Actual-App (iOS oder Android) und wähle beim Budget-Hinzufügen „Existing server". Gib als Server-URL die vollständige Adresse deines Hosts ein, z. B. http://192.168.1.100:5006 im LAN oder https://budget.meinedomain.de hinter einem Reverse Proxy. Anschließend das beim Bootstrap gesetzte Passwort eingeben.

Wie richte ich HTTPS ohne Reverse Proxy ein?

Actual Budget kann TLS direkt aktivieren: Lege die Zertifikatsdateien in einem Unterordner von ./actual-data/certs/ ab und setze in der compose.yaml die Variablen ACTUAL_HTTPS_KEY=/data/certs/privkey.pem und ACTUAL_HTTPS_CERT=/data/certs/fullchain.pem. Für automatisches HTTPS per Let's Encrypt ist ein vorgelagerter Reverse Proxy wie Caddy bequemer.

Was ist der Unterschied zwischen Docker Hub und der GitHub Container Registry?

Beide Registries veröffentlichen inhaltlich identische Images. Das Docker Hub-Image heißt actualbudget/actual-server, das GHCR-Image ghcr.io/actualbudget/actual (ohne -server). Die offizielle Dokumentation empfiehlt das Docker Hub-Image; für Umgebungen mit strikten Zugriffsregeln auf externe Registries kann das GHCR-Image als Alternative dienen.

Wie unterstützt Actual Budget mehrere Nutzer?

Mehrere Geräte oder Nutzer können sich mit demselben Server verbinden und separate Budget-Dateien anlegen. Für erweiterte Zugriffsszenarien kann die Login-Methode via ACTUAL_LOGIN_METHOD auf header (HTTP-Header-Auth durch Reverse Proxy) oder openid (OpenID Connect) umgestellt werden.

Fazit

Actual Budget ist einer der seltenen Self-Hosting-Stacks, bei denen die Einfachheit wirklich durchgängig ist: ein Container, ein Volume, kein externer Datenbankdienst. Wer nach dem Umschlag-Prinzip budgetiert und dabei keine Finanzdaten in fremde Hände geben möchte, bekommt hier eine ausgereifte, aktiv weiterentwickelte Lösung mit breiter Community. Der Einstieg gelingt in unter zehn Minuten, die laufenden Kosten beschränken sich auf Strom und Speicherplatz. Wer den Stack langfristig betreiben möchte, sollte den Schritt zu HTTPS und einem automatisierten Backup-Prozess nicht aufschieben.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren – Voraussetzung für diesen Stack
  2. Caddy als Reverse Proxy mit automatischem HTTPS einrichten – Ideal für den öffentlichen Zugriff auf Actual Budget
  3. Restic Backup auf Linux einrichten und automatisieren – Automatisches Backup des actual-data-Ordners
  4. Docker Compose absichern: Secrets, Healthchecks, Non-Root – Best Practices für den Produktivbetrieb

Offizielle Quellen: Actual Budget – Docker-Installationsdokumentation | Konfigurationsvariablen | Offizielles docker-compose.yml auf GitHub | Docker Hub: actualbudget/actual-server