Come installare Actual Budget su un VPS
Installa Actual Budget con Docker Compose: scopri volume dati, obbligo HTTPS per Web Crypto, primo budget, importazioni bancarie e backup.
Cosa stai creando
Actual Budget è un'app per la gestione del budget con il metodo delle buste, installata sul proprio server. È la risposta abituale per chi cerca un'alternativa a YNAB che possa essere ospitata autonomamente. Il server usa un solo container, un solo volume di dati e un solo nome HTTPS. Tutto ciò che serve per un budget normale funziona senza problemi sul VPS più piccolo disponibile, perché il server archivia soprattutto file e li sincronizza.
È utile comprendere l'architettura prima di eseguire qualsiasi comando. Il budget è un database SQLite che risiede nel browser e in ogni app mobile. Il server che stai per installare è un endpoint di sincronizzazione: conserva l'elenco degli account, i file del budget e il registro delle modifiche che permette a un telefono e a un laptop di mantenere gli stessi dati. Per questo l'app continua a funzionare quando il server è inattivo e la perdita del server non comporta la perdita del budget, finché almeno un client conserva ancora una copia.
Perché il server richiede HTTPS
Actual richiede HTTPS, e non è una formalità. I browser espongono la Web Crypto API, l'interfaccia che Actual usa per la crittografia end-to-end, solo in quello che la specifica definisce contesto sicuro. Un contesto sicuro è https:// o http://localhost. Se si accede all'app da http://203.0.113.10:5006 con un browser su un'altra macchina, queste funzionalità non sono semplicemente disponibili, perché il browser non le ha rese accessibili alla pagina. Anche le build mobili ufficiali rifiutano un URL del server http:// non protetto.
Sono quindi possibili due configurazioni. Si può installare un certificato reale su un nome reale davanti al container, come descritto in questa guida. In alternativa, si può fornire al server un certificato autofirmato con ACTUAL_HTTPS_KEY e ACTUAL_HTTPS_CERT, come documentato dal progetto, accettando un avviso del browser su ogni dispositivo. Un certificato gratuito di Let's Encrypt richiede cinque minuti, quindi conviene scegliere la prima opzione.
Installare Actual Budget con Docker Compose
Installare prima Docker se il server è appena configurato. Se la sintassi del file Compose è nuova, la guida Nozioni di base su Docker Compose per un VPS descrive i campi usati di seguito.
sudo install -d -m 755 /opt/actual
sudo install -d -m 700 /opt/actual/dataScrivere /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:/dataNel file sono importanti tre dettagli.
L'immagine è actualbudget/actual-server:latest, pubblicata dal progetto su Docker Hub e replicata in ghcr.io/actualbudget/actual. È disponibile un tag latest-alpine per i dispositivi a basso consumo.
Il container scrive tutto in /data. Al suo interno sono presenti server-files, che contiene account.sqlite con le credenziali di accesso e i token di sessione, e user-files, che contiene i file del budget. Montare quel percorso, altrimenti il comando docker compose pull successivo elimina il budget. ACTUAL_DATA_DIR può spostarlo, ma il valore predefinito va bene.
La porta viene pubblicata solo su 127.0.0.1. Un semplice 5006:5006 pubblica la porta su tutte le interfacce. Docker inserisce le proprie regole prima di ufw, quindi l'applicazione sarebbe esposta a Internet anche con un firewall che nega tutto il traffico. Questo comportamento è spiegato in perché le porte pubblicate da Docker ignorano ufw. Il binding sull'interfaccia di loopback consente di raggiungere l'applicazione solo al reverse proxy sullo stesso server.
Avviarlo:
cd /opt/actual
docker compose up --detach
docker compose logs -f actualIl log si stabilizza quando il server segnala che è in ascolto sulla porta 5006. Verificare localmente prima di modificare il DNS:
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5006/Un 200 indica che l'applicazione sta fornendo il servizio. Un curl: (7) Failed to connect indica che il container non è in esecuzione e docker compose ps mostra che è terminato. La causa abituale è un problema di autorizzazioni sul volume montato, visibile come una riga EACCES nel log.
Configurare un certificato e un nome reale
Punta un record A al VPS, budget.example.com, e attendi che la risoluzione sia completata. Installa quindi nginx e rilascia il certificato. La guida Certbot su Ubuntu 24.04 con nginx descrive in dettaglio il rilascio e il timer per il rinnovo.
Il blocco 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 è la riga che viene spesso dimenticata. Durante una sincronizzazione completa, il file del budget viene caricato per intero. Nginx consente per impostazione predefinita un corpo della richiesta di 1 MB. Quando il file supera questo limite, la sincronizzazione non riesce e nel log di accesso di nginx compare 413 Request Entity Too Large, mentre l'applicazione mostra solo un errore generico di sincronizzazione. Il server ha limiti separati: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB è 20 per impostazione predefinita e ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB è 50. Imposta quindi il limite di nginx al di sopra del valore applicabile.
Ricarica la configurazione ed esegui il test:
sudo nginx -t && sudo systemctl reload nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://budget.example.com/Prima esecuzione: la password e il primo file di bilancio
Apri https://budget.example.com in un browser. La prima schermata chiede di impostare una password per il server. Questa password protegge l'intero server, quindi generane una lunga e casuale e conservala in un luogo che potrai ritrovare, ad esempio in un gestore di password Vaultwarden self-hosted. Non è necessario creare account utente. Il server di Actual usa una sola password per progettazione, quindi condividere un bilancio significa condividere quella password.
Crea quindi un file di bilancio. Actual chiede se vuoi abilitare la crittografia end-to-end. Rispondi di sì: il server memorizzerà solo testo cifrato, la scelta corretta per i dati finanziari archiviati su una macchina a noleggio. Il costo è concreto: la password di crittografia non raggiunge mai il server. Se la perdi, il file non è recuperabile e non esiste alcuna procedura di reimpostazione. Annotala prima di proseguire oltre questa schermata.
Imposta i saldi iniziali usando i valori attuali della tua banca, invece di importare anni di cronologia. Il metodo di bilancio a buste parte dal denaro che hai ora, quindi non perdi nulla rinunciando alla cronologia precedente.
Importazione delle transazioni
Qui è importante essere onesti più che entusiasti, perché l'importazione è il motivo principale per cui le persone abbandonano i software di budgeting self-hosted.
L'inserimento manuale è la base e funziona sempre. Con il metodo delle buste, è probabilmente proprio questo il punto: digitare un acquisto aiuta a notarlo.
L'importazione da file gestisce la maggior parte dei dati. Actual legge CSV, QIF, OFX e QFX, e ogni banca esporta almeno uno di questi formati. Importa i dati per ogni account dalla schermata dell'account, associa le colonne una sola volta e Actual ricorderà quel layout per l'account.
È disponibile la sincronizzazione automatica con le banche, ma richiede un servizio di terze parti perché il server non può comunicare direttamente con le banche. Actual supporta SimpleFIN Bridge per le banche nordamericane, Enable Banking per l'Europa, Akahu per la Nuova Zelanda e Pluggy.ai per il Brasile. GoCardless è ancora supportato, ma non accetta nuovi account. Devi registrarti direttamente presso il provider, generare le credenziali e aggiungerle al server. A luglio 2026, SimpleFIN Bridge applica un costo di 15 dollari statunitensi all'anno per un massimo di 25 istituti; gli altri servizi hanno prezzi diversi.
Prima di affidarti a questa funzione, devi accettare due limiti. Le credenziali API risiedono sul server e non sono protette dalla crittografia end-to-end, perché il server deve utilizzarle. Inoltre, Actual non esegue il polling: la sincronizzazione viene avviata premendo un pulsante e non è un job in background.
Backup: perché si tratta solo di file
Tutto ciò che serve si trova in /opt/actual/data. Non è necessario esportare dati né creare un dump del database tramite script.
L'unico rischio riguarda SQLite. Se copi account.sqlite mentre il server vi sta scrivendo, potresti acquisire una transazione non completata. Te ne accorgerai solo quando proverai a ripristinare i dati. Arresta il container per i pochi secondi necessari alla copia:
cd /opt/actual
docker compose stop
restic -r sftp:backup@backup.example.com:/srv/restic backup /opt/actual/data
docker compose startPianifica questa operazione seguendo l'approccio descritto in backup restic su un VPS, che tratta la configurazione del repository, la conservazione dei backup e la procedura di ripristino. Esegui la procedura di ripristino. Un backup che non hai mai ripristinato è solo un'ipotesi.
I backup lato client di Actual sono separati e vale la pena conoscerli. Il browser conserva copie recenti del file di budget, accessibili dal menu del file. Questo permette di gestire il caso in cui elimini per errore una categoria senza intervenire sul server.
Aggiornamento del server
cd /opt/actual
docker compose pull
docker compose up --detachCompose ricrea il container dalla nuova immagine e ricollega lo stesso volume, quindi i dati restano disponibili. Aggiornare anche i client. Le versioni del server e dell'applicazione devono rimanere compatibili; un client molto più vecchio del server può rifiutare la sincronizzazione e mostrare un messaggio di mancata corrispondenza delle versioni. Eseguire un backup prima di un salto di versione principale, perché le migrazioni vengono eseguite al primo avvio e non è possibile effettuare il downgrade.
Cosa si interrompe e cosa vedrai
L'applicazione si carica, ma la sincronizzazione non termina mai. Controlla il log degli accessi di nginx per 413. Il valore di client_max_body_size è troppo basso. Un 502 indica invece che nginx è attivo, ma il container non lo è.
Le opzioni di crittografia mancano oppure l'app mobile rifiuta l'URL. La pagina non si trova in un contesto sicuro. La barra degli indirizzi mostrerà http:// con un indirizzo IP o un nome host che non è localhost. Correggi il certificato invece di aggirare il problema.
Viene visualizzato un messaggio che indica che il file del budget non è compatibile con questa versione. Le versioni del client e del server non sono più allineate. Aggiorna entrambi alla stessa release, quindi ricarica la pagina.
Il container si riavvia in un ciclo continuo. Leggi docker compose logs actual. Un errore di autorizzazione su /data indica che la directory montata non è scrivibile dall'utente del container. Un errore di indirizzo già in uso indica che un altro processo sta già utilizzando la porta 5006 sull'interfaccia loopback.
Il primo caricamento è lento. Quando apri il file del budget, l'intero file viene scaricato nel browser. Si tratta di un unico trasferimento di grandi dimensioni, seguito da letture locali. Non è un problema di dimensionamento del server e aggiungere RAM non cambierà la situazione.
FAQ
Actual Budget richiede HTTPS per funzionare?
Sì, in pratica. La crittografia end-to-end di Actual usa la Web Crypto API del browser, che i browser espongono solo in un contesto sicuro, ovvero https:// o http://localhost. Tramite HTTP semplice da un altro computer queste funzionalità non sono disponibili e le app mobili ufficiali rifiutano l'URL di un server HTTP semplice. Usa un certificato Let's Encrypt su un hostname reale oppure un certificato autofirmato con ACTUAL_HTTPS_KEY e ACTUAL_HTTPS_CERT se utilizzi esclusivamente un browser desktop.
Actual può importare automaticamente le transazioni bancarie?
Solo tramite un servizio di terze parti a cui devi registrarti personalmente: SimpleFIN Bridge in Nord America, Enable Banking in Europa, Akahu in Nuova Zelanda oppure Pluggy.ai in Brasile. GoCardless è supportato, ma non accetta nuovi account. Queste credenziali API risiedono sul server e non sono coperte dalla crittografia end-to-end. Anche la sincronizzazione è manuale: devi premere un pulsante e non viene eseguito alcun polling in background. L'importazione di file CSV, QIF, OFX e QFX non richiede alcun servizio di terze parti.
Che cosa devo includere esattamente nel backup?
La directory dei dati montata, che in questa guida è /opt/actual/data. Contiene server-files/account.sqlite con gli accessi e le sessioni e user-files con i file del budget. Arresta il container prima di copiare i dati, perché la copia di un database SQLite in uso può includere una scrittura parziale. Nessun altro elemento sul server contiene dati persistenti.
Che cosa succede se perdo la password di crittografia?
Il file non può essere recuperato. La password non raggiunge mai il server, che è proprio lo scopo della crittografia end-to-end, quindi non esiste una procedura di reimpostazione né un canale di assistenza per recuperarla. Salvala in un password manager non appena crei il file e conserva una copia in un luogo che non dipenda dallo stesso server.
Di quante risorse server ha bisogno Actual Budget?
Di pochissime. Il container distribuisce risorse statiche e file, mentre i calcoli del budget vengono eseguiti nel browser. Un vCPU condiviso con 1 GB di RAM è sufficiente per eseguirlo senza problemi e la directory dei dati di un budget familiare con diversi anni di cronologia rimane nell'ordine di alcune decine di megabyte. Lo spazio su disco viene occupato dai backup e dagli altri container, non da Actual.