Paano i-self-host ang Actual Budget sa VPS
I-run ang Actual Budget sa VPS gamit ang Docker Compose: alamin ang data volume, bakit kailangan ng browser ang HTTPS, bank imports, at tamang backups.
Mga itinatayo mo
Ang Actual Budget ay isang self-hosted envelope budgeting app. Ito ang karaniwang sagot kapag naghahanap ang mga tao ng YNAB alternative na maaari nilang i-host mismo. Isang container, isang data volume, at isang HTTPS name ang kailangan sa server. Kumportable itong tumakbo sa pinakamaliit na VPS na maaari mong rentahan dahil pangunahing nagse-save lang ng files at nagsi-sync ang server.
Mahalagang maunawaan muna ang architecture bago ka mag-type ng kahit ano. Ang budget mismo ay isang SQLite database na nasa browser mo at nasa bawat mobile app. Ang server na ii-install mo ay isang sync endpoint. Naglalaman ito ng listahan ng accounts, mga budget file, at change log na ginagamit para magtugma ang data sa phone at laptop. Kaya gumagana pa rin ang app kapag down ang server. Kaya hindi mawawala ang budget mo kapag nawala ang server, basta may isang client na may hawak pa ring kopya nito.
Bakit kailangan ng server ng HTTPS
Talagang nangangailangan ang Actual ng HTTPS, at hindi lang ito pormalidad. Ipinapakita lamang ng mga browser ang Web Crypto API, ang interface na ginagamit ng Actual para sa end-to-end encryption, kapag nasa tinatawag na secure context ayon sa specification. Ang secure context ay https:// o http://localhost. Kung i-load ang app mula sa http://203.0.113.10:5006 gamit ang browser sa ibang machine, wala roon ang mga feature na ito dahil hindi kailanman ipinasa ng browser ang mga ito sa page. Tinatanggihan din ng mga opisyal na mobile build ang plain na http:// server URL.
May dalawang setup na maaaring gamitin. Maglagay ng tunay na certificate sa tunay na domain name sa harap ng container, gaya ng ginagawa ng guide na ito. O bigyan ang server ng self-signed certificate gamit ang ACTUAL_HTTPS_KEY at ACTUAL_HTTPS_CERT, gaya ng nakadokumento sa project, at tanggapin ang browser warning sa bawat device. Limang minuto lang ang pagkuha ng libreng certificate mula sa Let's Encrypt, kaya piliin ang unang option.
I-install ang Actual Budget gamit ang Docker Compose
I-install muna ang Docker kung bagong setup ang server. Kung bago sa iyo ang syntax ng Compose file, ipinapaliwanag ng gabay na mga pangunahing kaalaman sa Docker Compose para sa isang VPS ang mga field na gagamitin sa ibaba.
sudo install -d -m 755 /opt/actual
sudo install -d -m 700 /opt/actual/dataIsulat ang /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:/dataMahalaga ang tatlong detalye sa file na iyon.
Ang image ay actualbudget/actual-server:latest, na inilabas ng project sa Docker Hub at may mirror sa ghcr.io/actualbudget/actual. May latest-alpine tag para sa mga machine na mababa ang power.
Isinusulat ng container ang lahat sa ilalim ng /data. Sa loob nito, makikita ang server-files, na naglalaman ng account.sqlite kasama ang iyong login at session tokens, at user-files, na naglalaman mismo ng mga budget file. I-mount ang path na iyon; kung hindi, buburahin ng susunod na docker compose pull ang iyong budget. Maaaring ilipat ito ng ACTUAL_DATA_DIR, pero maayos na ang default.
Sa 127.0.0.1 lang naka-publish ang port. Ang simpleng 5006:5006 ay nagpa-publish sa bawat interface, at inuuna ng Docker ang sarili nitong rules kaysa sa ufw. Dahil dito, magiging bukas sa internet ang app kahit may deny-all firewall. Ipinaliliwanag ang sorpresang ito sa kung bakit nilalampasan ng Docker published ports ang ufw. Kapag naka-bind sa loopback, ang reverse proxy lang sa parehong server ang makaka-access dito.
Simulan ito:
cd /opt/actual
docker compose up --detach
docker compose logs -f actualMatatapos ang mga log kapag iniulat ng server na nakikinig ito sa port 5006. Suriin muna ito nang lokal bago baguhin ang DNS:
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5006/Ibig sabihin ng 200 ay naghahatid ng serbisyo ang app. Ibig sabihin ng curl: (7) Failed to connect ay hindi tumatakbo ang container, at ipapakita ng docker compose ps na nag-exit ito. Karaniwang sanhi nito ang permission problem sa naka-mount na volume, na makikita bilang linyang EACCES sa log.
Maglagay ng certificate at totoong pangalan sa harapan
Ituro ang isang A record sa VPS, budget.example.com, at hintaying mag-resolve ito. Pagkatapos, i-install ang nginx at mag-issue ng certificate. Sinasaklaw nang buo ng gabay na Certbot sa Ubuntu 24.04 gamit ang nginx ang pag-issue at ang renewal timer.
Ang 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;
}
}Ang client_max_body_size ang linyang madalas makalimutan. Buo ang ina-upload na budget file kapag full sync. Naka-default ang nginx sa 1 MB na request body, kaya kapag lumampas dito ang file, mabibigo ang sync at lalabas ang 413 Request Entity Too Large sa nginx access log, habang generic sync error lang ang ipinapakita ng app. May hiwalay na limit ang server: ang ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB ay default na 20 at ang ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB ay default na 50, kaya itakda ang limit ng nginx na mas mataas sa alinman sa mga limit na naaangkop sa iyo.
I-reload at subukan:
sudo nginx -t && sudo systemctl reload nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://budget.example.com/Unang pag-run: ang password at ang una mong budget file
Buksan ang https://budget.example.com sa isang browser. Hihilingin sa unang screen na magtakda ka ng server password. Pinoprotektahan ng password na iyon ang buong server, kaya bumuo ng mahaba at random na password at itago ito sa lugar na mahahanap mong muli, gaya ng isang self-hosted na password manager na Vaultwarden. Walang user account na kailangang gawin. Single-password ang disenyo ng server ng Actual, kaya ang pagbabahagi ng budget ay nangangahulugan ding pagbabahagi ng password na iyon.
Pagkatapos, gumawa ng budget file. Itatanong ng Actual kung ie-enable ang end-to-end encryption. Piliin ang oo at ciphertext lamang ang ise-save ng server. Ito ang tamang opsyon para sa financial data sa rented machine. May kapalit ito: hindi umaabot sa server ang encryption password, kaya kapag nawala ito, mawawala rin ang file at walang reset na available. Isulat ito bago ka magpatuloy mula sa screen na iyon.
Itakda ang starting balances batay sa kasalukuyang figures ng iyong bank, sa halip na mag-import ng ilang taong history. Gumagana ang envelope budgeting mula sa perang mayroon ka ngayon, kaya walang mawawala sa iyo kahit walang history.
Pagkuha ng mga transaksyon
Dito mas mahalaga ang pagiging tapat kaysa sa pagiging masigasig, dahil ang paraan ng pag-import ang pangunahing dahilan kung bakit sumusuko ang mga tao sa self-hosted budgeting.
Ang manual entry ang pinakapangunahing paraan at palagi itong gumagana. Para sa envelope method, masasabi ring ito ang mismong punto, dahil ang pag-type ng isang purchase ang tumutulong para mapansin mo ito.
Sinasaklaw ng file import ang karamihan ng mga transaksyon. Nabasa ng Actual ang CSV, QIF, OFX, at QFX, at bawat bangko ay nag-e-export ng kahit isa sa mga format na ito. Mag-import kada account mula sa screen ng account, i-map nang isang beses ang mga column, at tatandaan ng Actual ang layout na iyon para sa account.
May automatic bank sync, ngunit kailangan nito ng third-party service dahil hindi direktang makakonekta ang server sa mga bangko nang mag-isa. Sinusuportahan ng Actual ang SimpleFIN Bridge para sa mga bangko sa North America, Enable Banking para sa Europe, Akahu para sa New Zealand, at Pluggy.ai para sa Brazil. Sinusuportahan pa rin ang GoCardless, ngunit hindi na ito tumatanggap ng mga bagong account. Ikaw mismo ang gagawa ng account sa provider, mag-ge-generate ng credentials, at magdaragdag ng mga ito sa server. Ang SimpleFIN Bridge ay naniningil ng 15 US dollars bawat taon para sa hanggang 25 institutions noong July 2026, at iba ang pricing ng iba pang provider.
May dalawang limitasyong dapat tanggapin bago ka umasa rito. Nasa server ang API credentials at hindi saklaw ng end-to-end encryption, dahil kailangang gamitin ng server ang mga ito. Hindi rin nagpo-poll ang Actual: button na pinipindot mo ang nagsisimula ng sync, hindi ito background job.
Mga Backup, dahil mga file lamang ito
Nasa ilalim ng /opt/actual/data ang lahat ng mahalagang data. Walang export step at walang database dump na kailangang i-script.
Ang isang dapat bantayan ay SQLite. Kapag kinopya ang account.sqlite habang sinusulatan ito ng server, maaaring makuha ang transaksyong hindi pa tapos. Malalaman mo lamang ito kapag sinubukan mo nang mag-restore. Ihinto ang container sa ilang segundo habang isinasagawa ang pagkopya:
cd /opt/actual
docker compose stop
restic -r sftp:backup@backup.example.com:/srv/restic backup /opt/actual/data
docker compose startIlagay ito sa isang schedule gamit ang approach sa restic backups sa isang VPS, na sumasaklaw sa repository setup, retention, at restore drill. Isagawa ang restore drill. Ang backup na hindi mo pa na-restore ay hula lamang.
Hiwalay na bagay ang sariling client-side backups ng Actual, at mahalagang malaman ang mga ito. Nagpapanatili ang browser ng mga kamakailang kopya ng budget file. Maa-access ang mga ito mula sa file menu. Sapat ito para sa sitwasyong “aksidenteng nabura ko ang isang category” nang hindi ginagalaw ang server.
Pag-update ng server
cd /opt/actual
docker compose pull
docker compose up --detachMuling nililikha ng Compose ang container mula sa bagong image at ikinakabit muli ang parehong volume, kaya nananatili ang data. I-update rin ang mga client. Dapat magkalapit ang mga bersyon ng server at app. Maaaring tumangging mag-sync ang client na masyadong luma kaysa sa server at magpakita ng mensahe tungkol sa hindi tugmang bersyon. Gumawa ng backup bago lumipat sa mas bagong major version, dahil tumatakbo ang mga migration sa unang pagsisimula at walang paraan para mag-downgrade. Mas mapagparaya ang Actual sa floating na latest tag dahil directory ng mga file ang state nito. Iba ito sa app na gumagamit ng aktuwal na database. Ipinapaliwanag naman ng self-hosting ng Chatwoot ang paggamit ng pinned tags at ng pre-upgrade dump na kailangan sa ganitong proseso.
Mga failure at kung ano ang makikita mo
Naglo-load ang app pero hindi natatapos ang sync. Suriin ang nginx access log para sa 413. Ibig sabihin, masyadong mababa ang itinakdang client_max_body_size. Samantala, ang 502 ay nangangahulugang gumagana ang nginx pero hindi tumatakbo ang container.
Nawawala ang mga encryption option, o tinatanggihan ng mobile app ang URL. Wala sa secure context ang page. Ipapakita ng address bar ang http:// na may IP address o hostname na hindi localhost. Ayusin ang certificate sa halip na gumamit ng workaround.
May mensaheng hindi compatible ang budget file sa bersyong ito. Hindi na tugma ang mga bersyon ng client at server. I-update ang dalawa sa iisang release, pagkatapos ay i-reload.
Paulit-ulit na nagre-restart ang container. Basahin ang docker compose logs actual. Ang permission error sa /data ay nangangahulugang hindi writable ng user ng container ang naka-mount na directory. Ang address-in-use error ay nangangahulugang may ibang process nang gumagamit sa 5006 sa loopback.
Mabagal ang unang pag-load. Ida-download sa browser ang buong budget file kapag binuksan mo ito. Isang malaking transfer muna ito, saka gagawin ang mga lokal na pagbasa. Hindi ito problema sa server sizing, at hindi ito mababago ng pagdagdag ng RAM.
FAQ
Kailangan ba ng HTTPS ang Actual Budget para gumana?
Oo, sa aktuwal na paggamit. Gumagamit ang end-to-end encryption ng Actual ng Web Crypto API ng browser, at inilalantad lang ito ng mga browser sa isang secure context, gaya ng https:// o http://localhost. Kapag plain HTTP mula sa ibang machine, hindi available ang mga feature na ito, at tinatanggihan ng official mobile apps ang plain HTTP server URL. Gumamit ng Let's Encrypt certificate sa isang totoong hostname, o self-signed certificate na may ACTUAL_HTTPS_KEY at ACTUAL_HTTPS_CERT kung desktop browser lang ang palagi mong gagamitin.
Maaari bang awtomatikong mag-import ang Actual ng mga transaksyon ko sa bangko?
Sa pamamagitan lang ng third-party service na ikaw mismo ang isi-sign up: SimpleFIN Bridge sa North America, Enable Banking sa Europe, Akahu sa New Zealand, o Pluggy.ai sa Brazil. Supported ang GoCardless, pero hindi na ito tumatanggap ng bagong accounts. Nasa server mo ang mga API credential na iyon at hindi saklaw ng end-to-end encryption. Manual din ang sync, kaya kailangan mong pindutin ang isang button at walang nagpo-poll sa background. Hindi nangangailangan ng third party ang pag-import ng CSV, QIF, OFX, at QFX.
Ano mismo ang kailangan kong i-back up?
Ang mounted data directory, na /opt/actual/data sa guide na ito. Naglalaman ito ng server-files/account.sqlite na may mga login at session, at user-files na may mga budget file. Ihinto ang container bago kumopya, dahil maaaring partial write ang makuha kapag kinopya ang isang live SQLite database. Walang ibang state na naka-store sa server.
Ano ang mangyayari kung mawala ko ang encryption password?
Hindi na mare-recover ang file. Hindi kailanman ipinapadala ang password sa server, na siyang pangunahing layunin ng end-to-end encryption, kaya walang reset at walang support path. I-store ito sa password manager kaagad pagkatapos mong gawin ang file, at magtabi ng kopya sa lugar na hindi umaasa sa server ding ito.
Gaano karaming server resources ang kailangan ng Actual Budget?
Napakakaunti. Nagse-serve ang container ng static assets at mga file, at sa browser ginagawa ang mga kalkulasyon ng budget. Tatakbo ito nang maayos sa isang shared vCPU na may 1 GB na RAM, at mananatili sa sampu-sampung megabytes ang data directory para sa household budget na may ilang taong history. Ang disk pressure ay nagmumula sa mga backup mo at sa iba mo pang container, hindi sa Actual. Kung nagsa-size ka ng box na kailangang magpatakbo ng mas resource-intensive na application kasabay nito, photo server ang karaniwang nagtatakda ng minimum requirement, kaya tingnan muna kung gaano karaming RAM ang aktuwal na kailangan ng PhotoPrism at Immich bago pumili ng plan.