Actual Budget per Docker auf dem eigenen VPS hosten
Installieren Sie Actual Budget per Docker Compose auf einem VPS. Dieser Leitfaden erklärt Datenvolume, HTTPS-Pflicht, erste Budgetdatei, Bankimporte und Backups.
Was Sie erstellen
Actual Budget ist eine selbst gehostete Anwendung für Umschlagbudgetierung. Sie ist die übliche Antwort, wenn eine selbst hostbare Alternative zu YNAB gesucht wird. Der Server besteht aus einem Container, einem Datenvolume und einem HTTPS-Namen. Alle Funktionen, die ein normales Budget benötigt, laufen problemlos auf dem kleinsten mietbaren VPS. Der Server speichert hauptsächlich Dateien und synchronisiert sie.
Die Architektur sollten Sie verstehen, bevor Sie Befehle eingeben. Das Budget selbst ist eine SQLite-Datenbank. Sie liegt im Browser und in jeder mobilen App. Der Server, den Sie gleich installieren, ist ein Synchronisierungsendpunkt. Er enthält die Kontoliste, die Budgetdateien und das Änderungsprotokoll. Damit können Telefon und Laptop denselben Stand verwenden. Deshalb funktioniert die Anwendung weiter, wenn der Server nicht erreichbar ist. Der Verlust des Servers führt außerdem nicht zum Verlust Ihres Budgets, solange mindestens ein Client noch eine Kopie besitzt.
Warum der Server HTTPS benötigt
Actual benötigt HTTPS tatsächlich. Das ist keine Formalität. Browser stellen die Web Crypto API, die Actual für die Ende-zu-Ende-Verschlüsselung verwendet, nur in einem sicheren Kontext bereit. Laut Spezifikation ist ein sicherer Kontext https:// oder http://localhost. Wenn Sie die Anwendung von http://203.0.113.10:5006 in einem Browser auf einem anderen Rechner laden, sind diese Funktionen nicht verfügbar, weil der Browser sie der Seite nicht bereitgestellt hat. Die offiziellen mobilen Builds lehnen außerdem eine einfache http://-Server-URL ab.
Daher gibt es zwei praktikable Konfigurationen. Sie können vor dem Container ein echtes Zertifikat für einen echten Namen bereitstellen. Das ist die Konfiguration in dieser Anleitung. Oder Sie geben dem Server mit ACTUAL_HTTPS_KEY und ACTUAL_HTTPS_CERT ein selbstsigniertes Zertifikat, wie es in der Projektdokumentation beschrieben ist, und akzeptieren auf jedem Gerät eine Browserwarnung. Ein kostenloses Zertifikat von Let's Encrypt ist in fünf Minuten eingerichtet. Verwenden Sie daher die erste Option.
Actual Budget mit Docker Compose installieren
Installieren Sie Docker zuerst, wenn der Server frisch eingerichtet ist. Wenn die Syntax von Compose-Dateien für Sie neu ist, beschreibt der Leitfaden Docker-Compose-Grundlagen für einen VPS die unten verwendeten Felder.
sudo install -d -m 755 /opt/actual
sudo install -d -m 700 /opt/actual/dataSchreiben Sie /opt/actual/docker-compose.yml:
services:
actual:
image: actualbudget/actual-server:latest
container_name: actual
restart: unless-stopped
ports:
- '127.0.0.1:5006:5006'
volumes:
- ./data:/dataIn dieser Datei sind drei Details wichtig.
Das Image ist actualbudget/actual-server:latest. Das Projekt veröffentlicht es auf Docker Hub und spiegelt es unter ghcr.io/actualbudget/actual. Für Geräte mit geringer Rechenleistung gibt es den Tag latest-alpine.
Der Container schreibt alle Daten unter /data. Darin finden Sie server-files mit account.sqlite, das Ihre Anmelde- und Sitzungstoken enthält, sowie user-files, das die Budgetdateien selbst enthält. Binden Sie diesen Pfad ein. Andernfalls verwirft docker compose pull Ihr Budget beim nächsten Start. ACTUAL_DATA_DIR kann den Pfad ändern, aber der Standardwert ist geeignet.
Der Port wird nur auf 127.0.0.1 veröffentlicht. Ein unbeschränktes 5006:5006 veröffentlicht ihn auf allen Schnittstellen. Docker schreibt seine eigenen Regeln vor den Regeln von ufw. Dadurch wäre die Anwendung auch bei einer Firewall mit standardmäßig verweigertem Zugriff aus dem Internet erreichbar. Warum von Docker veröffentlichte Ports ufw umgehen erklärt dieses Verhalten. Die Bindung an die Loopback-Schnittstelle bedeutet, dass nur der Reverse Proxy auf demselben Server die Anwendung erreichen kann.
Starten Sie den Container:
cd /opt/actual
docker compose up --detach
docker compose logs -f actualDie Protokollausgabe ist vollständig, sobald der Server meldet, dass er auf Port 5006 lauscht. Prüfen Sie die Anwendung lokal, bevor Sie DNS konfigurieren:
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5006/Ein 200 bedeutet, dass die Anwendung Anfragen verarbeitet. curl: (7) Failed to connect bedeutet, dass der Container nicht läuft. docker compose ps zeigt, dass der Container beendet wurde. Die häufigste Ursache ist ein Berechtigungsproblem auf dem eingebundenen Volume. Im Protokoll ist es als Zeile vom Typ EACCES zu erkennen.
Zertifikat und echten Namen vorschalten
Verweisen Sie einen A-Record auf den VPS, budget.example.com, und warten Sie, bis er aufgelöst wird. Installieren Sie anschließend nginx und stellen Sie das Zertifikat aus. Der Leitfaden Certbot unter Ubuntu 24.04 mit nginx beschreibt die Ausstellung und den Timer für die Erneuerung vollständig.
Der Proxy-Block:
server {
listen 443 ssl;
http2 on;
server_name budget.example.com;
ssl_certificate /etc/letsencrypt/live/budget.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/budget.example.com/privkey.pem;
client_max_body_size 100m;
location / {
proxy_pass http://127.0.0.1:5006;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}client_max_body_size ist die Zeile, die häufig vergessen wird. Bei einer vollständigen Synchronisierung wird die Budgetdatei als Ganzes hochgeladen. nginx begrenzt den Request-Body standardmäßig auf 1 MB. Sobald die Datei größer wird, schlägt die Synchronisierung fehl. Im nginx-Access-Log erscheint dann 413 Request Entity Too Large, während die Anwendung nur einen allgemeinen Synchronisierungsfehler anzeigt. Der Server hat eigene, separate Grenzwerte: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB ist standardmäßig auf 20 und ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB auf 50 gesetzt. Setzen Sie das nginx-Limit daher über den für Sie geltenden Wert.
Neu laden und testen:
sudo nginx -t && sudo systemctl reload nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://budget.example.com/Erster Start: das Passwort und Ihre erste Budgetdatei
Öffnen Sie https://budget.example.com in einem Browser. Auf dem ersten Bildschirm legen Sie ein Serverpasswort fest. Dieses einzelne Passwort schützt den gesamten Server. Erzeugen Sie daher ein langes, zufälliges Passwort und bewahren Sie es an einem Ort auf, an dem Sie es wiederfinden, beispielsweise in einem selbst gehosteten Vaultwarden-Passwortmanager. Benutzerkonten müssen Sie nicht anlegen. Der Server von Actual ist bewusst auf ein einzelnes Passwort ausgelegt. Ein Budget zu teilen bedeutet daher, dieses Passwort zu teilen.
Erstellen Sie anschließend eine Budgetdatei. Actual fragt, ob die Ende-zu-Ende-Verschlüsselung aktiviert werden soll. Bestätigen Sie mit Ja. Der Server speichert dann ausschließlich Chiffretext. Für Finanzdaten auf einem gemieteten Server ist das die richtige Einstellung. Der Nachteil ist erheblich: Das Verschlüsselungspasswort wird nie an den Server übertragen. Wenn Sie es verlieren, ist die Datei verloren. Eine Zurücksetzung ist nicht möglich. Schreiben Sie das Passwort auf, bevor Sie diesen Bildschirm verlassen.
Übernehmen Sie als Anfangssalden die aktuellen Werte Ihrer Bank, statt die Historie mehrerer Jahre zu importieren. Die Umschlagbudgetierung setzt bei dem Geld an, das Ihnen jetzt zur Verfügung steht. Eine leere Historie verursacht daher keinen Nachteil.
Transaktionen importieren
Hier zählt Ehrlichkeit mehr als Begeisterung, denn der Import ist der wichtigste Grund, warum viele beim Self-Hosting einer Budgetanwendung aufgeben.
Die manuelle Erfassung ist die grundlegende Option und funktioniert immer. Bei einer Umschlagmethode ist sie möglicherweise sogar der eigentliche Zweck, denn durch das Eingeben eines Kaufs nehmen Sie ihn bewusst wahr.
Der Dateiimport übernimmt den größten Teil der Arbeit. Actual liest CSV, QIF, OFX und QFX, und jede Bank exportiert mindestens eines dieser Formate. Importieren Sie die Daten für jedes Konto über die Kontoansicht, ordnen Sie die Spalten einmal zu, und Actual merkt sich dieses Layout für das Konto.
Eine automatische Banksynchronisierung ist möglich. Sie benötigt einen Drittanbieterdienst, weil der Server nicht selbst mit Banken kommunizieren kann. Actual unterstützt SimpleFIN Bridge für nordamerikanische Banken, Enable Banking für Europa, Akahu für Neuseeland und Pluggy.ai für Brasilien. GoCardless wird weiterhin unterstützt, nimmt aber keine neuen Konten mehr an. Sie registrieren sich selbst beim Anbieter, erzeugen die Zugangsdaten und hinterlegen sie auf dem Server. SimpleFIN Bridge kostet im Juli 2026 15 US-Dollar pro Jahr für bis zu 25 Institute. Die anderen Anbieter haben eine abweichende Preisgestaltung.
Vor einer Abhängigkeit von dieser Funktion sollten Sie zwei Einschränkungen berücksichtigen. Die API-Zugangsdaten liegen auf dem Server und sind nicht durch Ende-zu-Ende-Verschlüsselung geschützt, weil der Server sie verwenden muss. Actual fragt außerdem nicht automatisch ab: Die Synchronisierung wird per Schaltfläche gestartet und läuft nicht als Hintergrundaufgabe.
Backups, weil es nur Dateien sind
Alles, was Sie benötigen, liegt unter /opt/actual/data. Es gibt keinen Exportschritt und keinen Datenbank-Dump, den Sie skripten müssten.
Die einzige Falle ist SQLite. Wenn Sie account.sqlite kopieren, während der Server darauf schreibt, kann die Kopie eine nicht abgeschlossene Transaktion enthalten. Das bemerken Sie erst beim Wiederherstellen. Stoppen Sie den Container für die wenigen Sekunden, die das Kopieren dauert:
cd /opt/actual
docker compose stop
restic -r sftp:backup@backup.example.com:/srv/restic backup /opt/actual/data
docker compose startPlanen Sie das mit dem Ansatz aus Restic-Backups auf einem VPS, der die Einrichtung des Repositorys, die Aufbewahrung und den Wiederherstellungstest abdeckt. Führen Sie den Wiederherstellungstest durch. Ein Backup, das Sie noch nie wiederhergestellt haben, ist nur eine Vermutung.
Die clientseitigen Backups von Actual sind davon getrennt und ebenfalls wichtig. Der Browser speichert aktuelle Kopien der Budgetdatei. Sie sind über das Dateimenü erreichbar. Damit lässt sich der Fall „Ich habe versehentlich eine Kategorie gelöscht“ beheben, ohne den Server überhaupt anzufassen.
Server aktualisieren
cd /opt/actual
docker compose pull
docker compose up --detachCompose erstellt den Container aus dem neuen Image neu und bindet dasselbe Volume wieder ein. Die Daten bleiben dadurch erhalten. Aktualisieren Sie auch die Clients. Server- und App-Versionen sollten nahe beieinanderliegen. Ein Client, der deutlich älter als der Server ist, kann die Synchronisierung mit einer Meldung über nicht übereinstimmende Versionen verweigern. Erstellen Sie vor einem Sprung auf eine neue Hauptversion ein Backup. Migrationen laufen beim ersten Start. Ein Downgrade ist nicht möglich. Actual ist bei einem frei beweglichen latest-Tag unkritisch, weil sein Zustand aus einem Verzeichnis mit Dateien besteht. Das gilt nicht für eine Anwendung mit einer echten Datenbank. Self-Hosting von Chatwoot beschreibt die dafür erforderlichen festen Tags und den Dump vor dem Upgrade.
Was schiefgeht und was Sie sehen
Die Anwendung wird geladen, aber die Synchronisierung wird nie abgeschlossen. Prüfen Sie das nginx access log auf 413. Das bedeutet, dass client_max_body_size zu niedrig eingestellt ist. 502 bedeutet dagegen, dass nginx läuft und der Container nicht.
Verschlüsselungsoptionen fehlen, oder die mobile Anwendung lehnt die URL ab. Die Seite befindet sich nicht in einem sicheren Kontext. Die Adressleiste zeigt http:// mit einer IP-Adresse oder einem Hostnamen, der nicht localhost ist. Beheben Sie das Zertifikat, statt die Prüfung zu umgehen.
Es wird gemeldet, dass die Budgetdatei mit dieser Version nicht kompatibel ist. Die Client- und Serverversionen sind voneinander abgewichen. Aktualisieren Sie beide auf dasselbe Release und laden Sie die Anwendung neu.
Der Container wird fortlaufend neu gestartet. Lesen Sie docker compose logs actual. Ein Berechtigungsfehler bei /data bedeutet, dass das gemountete Verzeichnis für den Benutzer des Containers nicht beschreibbar ist. Ein Address-in-use-Fehler bedeutet, dass bereits ein anderer Prozess Port 5006 auf dem Loopback-Interface verwendet.
Der erste Ladevorgang wirkt langsam. Beim Öffnen wird die gesamte Budgetdatei in den Browser heruntergeladen. Danach erfolgen lokale Lesevorgänge. Das ist kein Problem der Serverdimensionierung. Mehr RAM ändert daran nichts.
FAQ
Benötigt Actual Budget HTTPS?
Ja, in der Praxis. Die Ende-zu-Ende-Verschlüsselung von Actual verwendet die Web Crypto API des Browsers. Browser stellen diese nur in einem sicheren Kontext bereit, also unter https:// oder http://localhost. Über unverschlüsseltes HTTP von einem anderen Rechner sind diese Funktionen nicht verfügbar. Die offiziellen mobilen Apps lehnen außerdem eine URL mit einem unverschlüsselten HTTP-Server ab. Verwenden Sie ein Let's-Encrypt-Zertifikat für einen echten Hostnamen. Alternativ können Sie ein selbst signiertes Zertifikat mit ACTUAL_HTTPS_KEY und ACTUAL_HTTPS_CERT verwenden, wenn Sie ausschließlich einen Desktop-Browser nutzen.
Kann Actual meine Bankumsätze automatisch importieren?
Nur über einen Drittanbieterdienst, bei dem Sie selbst ein Konto einrichten: SimpleFIN Bridge in Nordamerika, Enable Banking in Europa, Akahu in Neuseeland oder Pluggy.ai in Brasilien. GoCardless wird unterstützt, nimmt aber keine neuen Konten mehr an. Diese API-Zugangsdaten liegen auf Ihrem Server und sind nicht durch die Ende-zu-Ende-Verschlüsselung geschützt. Die Synchronisierung erfolgt ebenfalls manuell. Sie drücken eine Schaltfläche, und im Hintergrund wird nichts abgefragt. Für den Import von CSV, QIF, OFX und QFX ist überhaupt kein Drittanbieter erforderlich.
Was muss ich genau sichern?
Das eingebundene Datenverzeichnis, in dieser Anleitung /opt/actual/data. Es enthält server-files/account.sqlite mit Anmeldedaten und Sitzungen sowie user-files mit den Budgetdateien. Stoppen Sie den Container vor dem Kopieren. Beim Kopieren einer aktiven SQLite-Datenbank kann ein unvollständiger Schreibvorgang erfasst werden. Auf dem Server enthält nichts anderes Zustandsdaten.
Was passiert, wenn ich das Verschlüsselungspasswort verliere?
Die Datei kann nicht wiederhergestellt werden. Das Passwort erreicht niemals den Server. Genau das ist der Zweck der Ende-zu-Ende-Verschlüsselung. Daher gibt es keine Möglichkeit zum Zurücksetzen und keinen Supportweg. Speichern Sie das Passwort sofort nach dem Erstellen der Datei in einem Passwortmanager. Bewahren Sie außerdem eine Kopie an einem Ort auf, der nicht von diesem Server abhängt.
Wie viel Serverkapazität benötigt Actual Budget?
Sehr wenig. Der Container stellt statische Ressourcen und Dateien bereit. Die Budgetberechnungen erfolgen im Browser. Ein gemeinsam genutzter vCPU mit 1 GB RAM reicht für den Betrieb ohne Probleme aus. Das Datenverzeichnis eines Haushaltsbudgets mit mehreren Jahren Historie bleibt im zweistelligen Megabytebereich. Die Speicherbelegung entsteht durch Ihre Backups und andere Container, nicht durch Actual. Wenn Sie einen Server dimensionieren, auf dem zusätzlich eine anspruchsvollere Anwendung laufen soll, bestimmt normalerweise ein Fotoserver die Mindestanforderungen. Prüfen Sie daher wie viel RAM PhotoPrism und Immich tatsächlich benötigen, bevor Sie einen Tarif auswählen. Für einen Medienstapel gilt dieselbe Logik: Die Transkodierung bestimmt die Anforderungen. Ein Browser-Frontend wie Halcyon, das eine Jellyfin-Bibliothek in eine begehbare Videothek der 90er-Jahre verwandelt, benötigt dagegen ungefähr so wenig Ressourcen wie Actual.