SSD Nodes Learn 8GB RAM — $66/rok
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-01

Actual Budget na własnym VPS z Docker Compose

Sprawdź, jak uruchomić Actual Budget na VPS: wolumin danych, wymagane HTTPS dla Web Crypto API, pierwszy budżet, import bankowy i kopie zapasowe.

Co jest instalowane

Actual Budget to hostowana samodzielnie aplikacja do budżetowania metodą kopertową. Jest standardowym wyborem dla osób szukających alternatywy dla YNAB, którą można hostować samodzielnie. Serwer działa w jednym kontenerze, korzysta z jednego woluminu danych i jednej nazwy HTTPS. Wszystkie funkcje potrzebne do prowadzenia budżetu działają bez problemu na najmniejszym dostępnym VPS, ponieważ serwer głównie przechowuje pliki i synchronizuje dane.

Przed wykonaniem poleceń należy zrozumieć architekturę. Sam budżet jest bazą danych SQLite przechowywaną w przeglądarce oraz w każdej aplikacji mobilnej. Instalowany serwer jest punktem końcowym synchronizacji. Przechowuje listę kont, pliki budżetów i dziennik zmian, który pozwala uzgodnić dane na telefonie i laptopie. Dlatego aplikacja nadal działa, gdy serwer jest niedostępny. Utrata serwera nie powoduje utraty budżetu, jeśli co najmniej jeden klient nadal przechowuje jego kopię.

Dlaczego serwer wymaga HTTPS

Actual wymaga protokołu HTTPS i nie jest to formalność. Przeglądarki udostępniają interfejs Web Crypto API, którego Actual używa do szyfrowania typu end-to-end, tylko w kontekście bezpiecznym, określanym w specyfikacji jako secure context. Bezpieczny kontekst to https:// lub http://localhost. Po otwarciu aplikacji z adresu http://203.0.113.10:5006 w przeglądarce na innym komputerze te funkcje po prostu nie są dostępne, ponieważ przeglądarka nie udostępniła ich stronie. Oficjalne wersje mobilne również odrzucają zwykły adres URL serwera http://.

Dostępne są więc dwie konfiguracje. Można umieścić przed kontenerem prawidłowy certyfikat dla rzeczywistej nazwy domenowej, co opisano w tym poradniku. Można też przekazać serwerowi certyfikat samopodpisany za pomocą ACTUAL_HTTPS_KEY i ACTUAL_HTTPS_CERT, zgodnie z dokumentacją projektu, oraz akceptować ostrzeżenie przeglądarki na każdym urządzeniu. Bezpłatny certyfikat Let's Encrypt można uzyskać w ciągu pięciu minut, dlatego zaleca się pierwszą opcję.

Instalowanie Actual Budget za pomocą Docker Compose

Najpierw zainstaluj Docker, jeśli serwer jest świeży. Jeśli składnia pliku Compose jest nowa, w przewodniku Podstawy Docker Compose dla VPS opisano użyte poniżej pola.

sudo install -d -m 755 /opt/actual
sudo install -d -m 700 /opt/actual/data

Zapisz /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:/data

W tym pliku istotne są trzy elementy.

Obraz to actualbudget/actual-server:latest, opublikowany przez projekt w Docker Hub i dostępny również pod adresem ghcr.io/actualbudget/actual. Dostępny jest tag latest-alpine przeznaczony dla urządzeń o niskiej mocy.

Kontener zapisuje wszystkie dane w /data. W tym katalogu znajdują się server-files, który zawiera account.sqlite z danymi logowania i tokenami sesji, oraz user-files, który zawiera właściwe pliki budżetu. Zamontuj tę ścieżkę. W przeciwnym razie następne docker compose pull usunie budżet. ACTUAL_DATA_DIR może zmienić tę lokalizację, ale warto pozostawić ustawienie domyślne.

Port jest publikowany wyłącznie na 127.0.0.1. Samo 5006:5006 publikuje port na wszystkich interfejsach. Docker umieszcza własne reguły przed regułami ufw, dlatego aplikacja byłaby dostępna z Internetu nawet przy zaporze blokującej cały ruch. To działanie opisano w wyjaśnieniu, dlaczego opublikowane porty Docker omijają ufw. Powiązanie z loopback oznacza, że dostęp do aplikacji ma tylko reverse proxy na tym samym serwerze.

Uruchom usługę:

cd /opt/actual
docker compose up --detach
docker compose logs -f actual

Log stabilizuje się, gdy serwer zgłosi nasłuchiwanie na porcie 5006. Sprawdź usługę lokalnie przed skonfigurowaniem DNS:

curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5006/

Wynik 200 oznacza, że aplikacja obsługuje żądania. Wynik curl: (7) Failed to connect oznacza, że kontener nie działa, a docker compose ps wyświetli informację o jego zakończeniu. Zwykle przyczyną jest problem z uprawnieniami do zamontowanego woluminu, widoczny w logu jako wiersz EACCES.

Umieść certyfikat i rzeczywistą nazwę z przodu

Skieruj rekord A na VPS, budget.example.com, i zaczekaj na propagację. Następnie zainstaluj nginx i wystaw certyfikat. Instrukcja Certbot w Ubuntu 24.04 z nginx szczegółowo opisuje wystawianie certyfikatu i licznik odnowienia.

Blok proxy:

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 to wiersz, o którym często się zapomina. Podczas pełnej synchronizacji plik budżetu jest przesyłany w całości. Domyślnie nginx zezwala na treść żądania o rozmiarze 1 MB. Gdy plik przekroczy ten rozmiar, synchronizacja kończy się niepowodzeniem, a w dzienniku dostępu nginx pojawia się 413 Request Entity Too Large. Aplikacja wyświetla wtedy tylko ogólny błąd synchronizacji. Serwer ma własne, niezależne limity: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB ma domyślną wartość 20, a ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB domyślną wartość 50. Ustaw limit nginx powyżej wartości właściwej dla danego przypadku.

Przeładuj konfigurację i wykonaj test:

sudo nginx -t && sudo systemctl reload nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://budget.example.com/

Pierwsze uruchomienie: hasło i pierwszy plik budżetu

Otwórz https://budget.example.com w przeglądarce. Na pierwszym ekranie należy ustawić hasło serwera. To hasło chroni cały serwer, dlatego należy wygenerować długie, losowe hasło i zapisać je w miejscu, w którym będzie można je później znaleźć, na przykład w samodzielnie hostowanym menedżerze haseł Vaultwarden. Nie trzeba tworzyć kont użytkowników. Serwer Actual został zaprojektowany do używania jednego hasła, dlatego udostępnienie budżetu oznacza udostępnienie tego hasła.

Następnie należy utworzyć plik budżetu. Actual zapyta, czy włączyć szyfrowanie end-to-end. Należy wybrać tę opcję. Wtedy serwer będzie przechowywać wyłącznie szyfrogram, co jest właściwym rozwiązaniem w przypadku danych finansowych przechowywanych na wynajętej maszynie. Ma to jednak istotną konsekwencję: hasło szyfrowania nigdy nie trafia na serwer. Jeśli zostanie utracone, plik zostanie utracony i nie będzie można zresetować tego hasła. Należy zapisać je przed przejściem dalej na tym ekranie.

Należy ustawić salda początkowe na podstawie bieżących danych banku, zamiast importować dane z wielu lat. Budżetowanie kopertowe działa od aktualnie posiadanych środków, dlatego brak wcześniejszej historii nie powoduje żadnych strat.

Importowanie transakcji

W tym miejscu ważniejsza jest rzetelność niż entuzjazm, ponieważ sposób importowania jest głównym powodem, dla którego użytkownicy rezygnują z samodzielnie hostowanego budżetowania.

Wprowadzanie ręczne stanowi podstawę i zawsze działa. W przypadku metody kopertowej jest to prawdopodobnie jej istota, ponieważ wpisanie zakupu powoduje zwrócenie na niego uwagi.

Import plików obsługuje większość danych. Actual odczytuje formaty CSV, QIF, OFX i QFX, a każdy bank udostępnia eksport w co najmniej jednym z nich. Import należy wykonywać dla każdego konta z poziomu ekranu konta. Mapowanie kolumn wykonuje się raz, a Actual zapamiętuje ten układ dla danego konta.

Dostępna jest automatyczna synchronizacja z bankiem, ale wymaga usługi zewnętrznej, ponieważ serwer nie może samodzielnie komunikować się z bankami. Actual obsługuje SimpleFIN Bridge dla banków w Ameryce Północnej, Enable Banking w Europie, Akahu w Nowej Zelandii oraz Pluggy.ai w Brazylii. GoCardless jest nadal obsługiwany, ale nie przyjmuje nowych kont. Konto u dostawcy należy założyć samodzielnie, wygenerować dane uwierzytelniające i dodać je do serwera. Od lipca 2026 SimpleFIN Bridge pobiera 15 dolarów amerykańskich rocznie za maksymalnie 25 instytucji, natomiast pozostali dostawcy stosują inne ceny.

Przed oparciem na tym rozwiązaniu należy zaakceptować 2 ograniczenia. Dane uwierzytelniające API znajdują się na serwerze i nie są objęte szyfrowaniem end-to-end, ponieważ serwer musi ich używać. Actual nie wykonuje też odpytywania cyklicznego: synchronizację uruchamia się przyciskiem, a nie jako zadanie w tle.

Kopie zapasowe, ponieważ chodzi tylko o pliki

Wszystkie istotne dane znajdują się w /opt/actual/data. Nie ma etapu eksportu ani zrzutu bazy danych, który trzeba skryptować.

Jedyną pułapką jest SQLite. Skopiowanie account.sqlite podczas zapisu przez serwer może uchwycić niedokończoną transakcję. Można się o tym przekonać dopiero podczas próby odtworzenia danych. Należy zatrzymać kontener na kilka sekund potrzebnych do wykonania kopii:

cd /opt/actual
docker compose stop
restic -r sftp:backup@backup.example.com:/srv/restic backup /opt/actual/data
docker compose start

Należy zaplanować wykonywanie kopii zgodnie z podejściem opisanym w kopie zapasowe restic na VPS, które obejmuje konfigurację repozytorium, zasady przechowywania oraz próbne odtworzenie danych. Należy wykonać próbne odtworzenie. Kopia zapasowa, z której nigdy nie odtworzono danych, jest tylko przypuszczeniem.

Własne kopie zapasowe po stronie klienta w Actual są odrębną funkcją i warto ją znać. Przeglądarka przechowuje ostatnie kopie pliku budżetu, dostępne z menu pliku. Umożliwia to rozwiązanie sytuacji „przypadkowo usunięto kategorię” bez ingerencji w serwer.

Aktualizacja serwera

cd /opt/actual
docker compose pull
docker compose up --detach

Compose odtwarza kontener na podstawie nowego obrazu i ponownie dołącza ten sam wolumin, dlatego dane zostają zachowane. Należy również zaktualizować klientów. Wersje serwera i aplikacji powinny być zbliżone. Klient znacznie starszy od serwera może odmówić synchronizacji i wyświetlić komunikat o niezgodności wersji. Przed przejściem na wyższą wersję główną należy wykonać kopię zapasową, ponieważ przy pierwszym uruchomieniu wykonywane są migracje i nie ma możliwości powrotu do starszej wersji.

Co nie działa i jakie będą objawy

Aplikacja ładuje się, ale synchronizacja nigdy się nie kończy. Należy sprawdzić dziennik dostępu nginx pod kątem 413. Oznacza to, że wartość client_max_body_size jest zbyt niska. Wystąpienie 502 oznacza natomiast, że nginx działa, a kontener nie.

Brakuje opcji szyfrowania lub aplikacja mobilna odrzuca adres URL. Strona nie działa w bezpiecznym kontekście. Na pasku adresu będzie widoczny wpis http:// z adresem IP lub nazwą hosta inną niż localhost. Należy naprawić certyfikat, a nie obchodzić problem.

Wyświetlany jest komunikat, że plik budżetu nie jest zgodny z tą wersją. Wersje klienta i serwera różnią się. Należy zaktualizować oba komponenty do tego samego wydania i ponownie załadować stronę.

Kontener uruchamia się ponownie w pętli. Należy odczytać docker compose logs actual. Błąd uprawnień dotyczący /data oznacza, że katalog zamontowany w kontenerze nie jest zapisywalny przez użytkownika kontenera. Błąd informujący o zajęciu adresu oznacza, że inny proces korzysta już z portu 5006 na interfejsie loopback.

Pierwsze ładowanie trwa długo. Cały plik budżetu jest pobierany do przeglądarki podczas jego otwierania. Jest to jeden duży transfer, po którym następują odczyty lokalne. Nie jest to problem z rozmiarem serwera, a zwiększenie ilości pamięci RAM tego nie zmieni.

FAQ

Czy Actual Budget wymaga HTTPS do działania?

Tak, w praktyce. Szyfrowanie end-to-end w Actual korzysta z Web Crypto API przeglądarki, a przeglądarki udostępniają ten interfejs tylko w bezpiecznym kontekście, czyli https:// lub http://localhost. Przy użyciu zwykłego HTTP z innego komputera te funkcje są niedostępne, a oficjalne aplikacje mobilne odrzucają adres URL serwera HTTP bez szyfrowania. Należy użyć certyfikatu Let's Encrypt dla rzeczywistej nazwy hosta albo certyfikatu z podpisem własnym wraz z ACTUAL_HTTPS_KEY i ACTUAL_HTTPS_CERT, jeśli serwer będzie używany wyłącznie w przeglądarce na komputerze stacjonarnym.

Czy Actual może automatycznie importować transakcje bankowe?

Tylko za pośrednictwem usługi zewnętrznej, w której konto zakłada się samodzielnie: SimpleFIN Bridge w Ameryce Północnej, Enable Banking w Europie, Akahu w Nowej Zelandii lub Pluggy.ai w Brazylii. GoCardless jest obsługiwany, ale obecnie nie przyjmuje nowych kont. Te dane uwierzytelniające API są przechowywane na serwerze i nie są objęte szyfrowaniem end-to-end. Synchronizację również uruchamia się ręcznie, więc należy nacisnąć przycisk; w tle nie jest wykonywane odpytywanie. Import plików CSV, QIF, OFX i QFX nie wymaga żadnej usługi zewnętrznej.

Co dokładnie należy uwzględnić w kopii zapasowej?

Należy uwzględnić zamontowany katalog danych, który w tym przewodniku jest oznaczony jako /opt/actual/data. Zawiera on server-files/account.sqlite z danymi logowania i sesjami oraz user-files z plikami budżetu. Przed skopiowaniem należy zatrzymać kontener, ponieważ kopiowanie używanej bazy SQLite może przechwycić niepełny zapis. Żadne inne dane stanu nie są przechowywane na serwerze.

Co się stanie w przypadku utraty hasła szyfrowania?

Pliku nie będzie można odzyskać. Hasło nigdy nie trafia na serwer, co jest podstawowym celem szyfrowania end-to-end, dlatego nie ma możliwości jego zresetowania ani uzyskania pomocy w odzyskaniu dostępu. Należy zapisać je w menedżerze haseł natychmiast po utworzeniu pliku oraz przechowywać kopię w miejscu niezależnym od tego serwera.

Jakich zasobów serwera wymaga Actual Budget?

Bardzo niewielkich. Kontener udostępnia zasoby statyczne i pliki, a obliczenia budżetu są wykonywane w przeglądarce. Jedna współdzielona jednostka vCPU i 1 GB pamięci RAM wystarczają do działania bez problemów, a katalog danych budżetu domowego z historią obejmującą kilka lat zajmuje kilkadziesiąt megabajtów. Obciążenie miejsca na dysku wynika z kopii zapasowych i innych kontenerów, a nie z Actual.