Cara Self-Host Actual Budget di VPS dengan Docker
Pelajari cara menjalankan Actual Budget di VPS dengan Docker Compose, termasuk volume data, HTTPS untuk Web Crypto API, impor bank, dan pencadangan.
Yang Anda Bangun
Actual Budget adalah aplikasi penganggaran berbasis amplop yang di-host sendiri. Aplikasi ini biasanya dipilih ketika orang mencari alternatif YNAB yang dapat mereka host sendiri. Servernya terdiri dari satu container, satu volume data, dan satu nama HTTPS. Semua fungsi yang diperlukan anggaran biasa dapat berjalan dengan baik pada VPS terkecil yang dapat Anda sewa, karena server terutama menyimpan file dan menyinkronkannya.
Arsitekturnya perlu dipahami sebelum Anda menjalankan perintah apa pun. Anggaran itu sendiri adalah database SQLite yang berada di dalam browser dan setiap aplikasi seluler Anda. Server yang akan Anda instal adalah endpoint sinkronisasi. Server ini menyimpan daftar akun, file anggaran, dan log perubahan yang memungkinkan ponsel dan laptop memiliki data yang sama. Karena itu, aplikasi tetap berfungsi saat server tidak aktif. Kehilangan server juga tidak menghilangkan anggaran Anda selama salah satu client masih menyimpan salinannya.
Mengapa server memerlukan HTTPS
Actual memerlukan HTTPS, dan ini bukan sekadar formalitas. Browser hanya menyediakan Web Crypto API, yaitu antarmuka yang digunakan Actual untuk enkripsi ujung ke ujung, dalam konteks aman yang disebutkan oleh spesifikasi. Konteks aman adalah https:// atau http://localhost. Muat aplikasi dari http://203.0.113.10:5006 di browser pada mesin lain, dan fitur tersebut tidak tersedia karena browser tidak pernah memberikannya kepada halaman tersebut. Build mobile resmi juga menolak URL server http:// biasa.
Jadi, ada dua konfigurasi yang dapat digunakan. Pasang sertifikat nyata pada nama domain nyata di depan container, seperti yang dilakukan panduan ini. Atau berikan server sertifikat yang ditandatangani sendiri dengan ACTUAL_HTTPS_KEY dan ACTUAL_HTTPS_CERT, seperti yang didokumentasikan oleh proyek, lalu terima peringatan browser pada setiap perangkat. Sertifikat gratis dari Let's Encrypt dapat diperoleh dalam lima menit, jadi gunakan opsi pertama.
Instal Actual Budget dengan Docker Compose
Instal Docker terlebih dahulu jika server masih baru. Jika sintaks file Compose masih baru bagi Anda, panduan dasar-dasar Docker Compose untuk VPS menjelaskan kolom yang digunakan di bawah ini.
sudo install -d -m 755 /opt/actual
sudo install -d -m 700 /opt/actual/dataTulis /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:/dataAda tiga hal penting dalam file tersebut.
Image-nya adalah actualbudget/actual-server:latest, yang dipublikasikan oleh proyek ke Docker Hub dan dicerminkan di ghcr.io/actualbudget/actual. Tersedia tag latest-alpine untuk mesin berdaya rendah.
Container menulis semua data di bawah /data. Di dalamnya terdapat server-files, yang menyimpan account.sqlite berisi kredensial login dan token sesi Anda, serta user-files, yang menyimpan file anggaran itu sendiri. Mount path tersebut. Jika tidak, perintah docker compose pull berikutnya akan menghapus anggaran Anda. ACTUAL_DATA_DIR dapat memindahkannya, tetapi nilai default sudah memadai.
Port hanya dipublikasikan pada 127.0.0.1. 5006:5006 tanpa alamat akan memublikasikan port pada semua interface. Docker menulis aturannya sendiri sebelum ufw, sehingga aplikasi akan terbuka ke internet meskipun firewall menolak semua koneksi. Penjelasan tentang perilaku ini tersedia di alasan port yang dipublikasikan Docker melewati ufw. Binding ke loopback berarti hanya reverse proxy pada server yang sama yang dapat mengaksesnya.
Jalankan:
cd /opt/actual
docker compose up --detach
docker compose logs -f actualLog akan stabil setelah server melaporkan bahwa server sedang mendengarkan pada port 5006. Periksa secara lokal sebelum mengubah DNS:
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5006/200 berarti aplikasi sedang melayani permintaan. curl: (7) Failed to connect berarti container tidak sedang berjalan, dan docker compose ps akan menampilkan bahwa container telah berhenti. Penyebab yang umum adalah masalah izin pada volume yang di-mount, yang terlihat sebagai baris EACCES dalam log.
Cantumkan sertifikat dan nama asli di bagian depan
Arahkan record A ke VPS, budget.example.com, lalu tunggu hingga resolusinya selesai. Kemudian instal nginx dan terbitkan sertifikat. Panduan Certbot di Ubuntu 24.04 dengan nginx membahas penerbitan dan timer perpanjangan secara lengkap.
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 adalah baris yang sering terlupakan. File anggaran diunggah secara utuh saat sinkronisasi penuh. Secara default, Nginx membatasi isi permintaan hingga 1 MB. Setelah ukuran file melebihi batas tersebut, sinkronisasi gagal dan 413 Request Entity Too Large muncul di log akses nginx, sedangkan aplikasi hanya menampilkan kesalahan sinkronisasi umum. Server memiliki batas terpisah: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB secara default bernilai 20 dan ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB bernilai 50. Jadi, tetapkan batas nginx di atas batas yang berlaku bagi Anda.
Muat ulang dan uji:
sudo nginx -t && sudo systemctl reload nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://budget.example.com/Penggunaan pertama: kata sandi dan file anggaran pertama Anda
Buka https://budget.example.com di browser. Layar pertama meminta Anda menetapkan kata sandi server. Kata sandi ini melindungi seluruh server, jadi buat kata sandi acak yang panjang dan simpan di tempat yang dapat Anda temukan kembali, misalnya di pengelola kata sandi Vaultwarden yang di-hosting sendiri. Tidak ada akun pengguna yang perlu dibuat. Server Actual dirancang untuk menggunakan satu kata sandi, sehingga berbagi anggaran berarti berbagi kata sandi tersebut.
Kemudian buat file anggaran. Actual akan menanyakan apakah enkripsi end-to-end ingin diaktifkan. Pilih ya. Server kemudian hanya menyimpan ciphertext. Ini adalah pilihan yang tepat untuk data keuangan di mesin sewaan. Namun, ada konsekuensinya: kata sandi enkripsi tidak pernah dikirim ke server. Jika Anda kehilangan kata sandi tersebut, file akan hilang dan tidak ada opsi reset. Catat kata sandi itu sebelum melanjutkan dari layar tersebut.
Tetapkan saldo awal berdasarkan angka terbaru dari bank Anda, bukan dengan mengimpor riwayat selama bertahun-tahun. Penganggaran berbasis amplop berjalan berdasarkan uang yang Anda miliki saat ini, sehingga tidak memiliki riwayat tidak menimbulkan kerugian.
Mengimpor transaksi
Di bagian ini, kejujuran lebih penting daripada antusiasme. Dukungan impor merupakan alasan utama orang berhenti menggunakan aplikasi penganggaran yang di-hosting sendiri.
Entri manual adalah dasar dan selalu berfungsi. Untuk metode amplop, entri manual bisa dikatakan sebagai tujuan utamanya, karena mengetikkan pembelian membuat Anda menyadarinya.
Impor file menangani sebagian besar transaksi. Actual dapat membaca CSV, QIF, OFX, dan QFX, dan setiap bank menyediakan setidaknya salah satu format tersebut. Impor setiap akun dari layar akun, petakan kolom satu kali, dan Actual akan mengingat tata letak tersebut untuk akun itu.
Sinkronisasi bank otomatis tersedia, tetapi memerlukan layanan pihak ketiga karena server tidak dapat berkomunikasi dengan bank secara mandiri. Actual mendukung SimpleFIN Bridge untuk bank di Amerika Utara, Enable Banking untuk Eropa, Akahu untuk Selandia Baru, dan Pluggy.ai untuk Brasil. GoCardless masih didukung, tetapi tidak menerima akun baru. Anda harus mendaftar sendiri ke penyedia layanan, membuat kredensial, lalu menambahkannya ke server. Per Juli 2026, SimpleFIN Bridge mengenakan biaya 15 dolar AS per tahun untuk hingga 25 institusi, sedangkan penyedia lainnya memiliki struktur harga yang berbeda.
Sebelum mengandalkan fitur ini, terima dua batasan berikut. Kredensial API tersimpan di server dan tidak dilindungi oleh enkripsi end-to-end, karena server harus menggunakannya. Actual juga tidak melakukan polling: sinkronisasi dilakukan dengan menekan tombol, bukan melalui tugas latar belakang.
Cadangan, karena hanya berupa file
Semua data penting berada di /opt/actual/data. Tidak ada langkah ekspor dan tidak ada pencadangan database yang perlu dibuat skripnya.
Satu hal yang perlu diperhatikan adalah SQLite. Menyalin account.sqlite saat server sedang menulis ke dalamnya dapat menangkap transaksi yang belum selesai. Anda mungkin baru mengetahuinya saat mencoba memulihkan data. Hentikan container selama beberapa detik yang diperlukan untuk menyalin:
cd /opt/actual
docker compose stop
restic -r sftp:backup@backup.example.com:/srv/restic backup /opt/actual/data
docker compose startJadwalkan proses tersebut menggunakan pendekatan dalam cadangan restic pada VPS. Pendekatan ini mencakup penyiapan repositori, retensi, dan uji pemulihan. Jalankan uji pemulihan. Cadangan yang belum pernah dipulihkan hanyalah perkiraan.
Cadangan sisi klien milik Actual sendiri merupakan hal yang terpisah dan perlu diketahui. Browser menyimpan salinan terbaru file anggaran, yang dapat diakses dari menu file. Fitur ini menangani kasus “saya tidak sengaja menghapus kategori” tanpa menyentuh server sama sekali.
Memperbarui server
cd /opt/actual
docker compose pull
docker compose up --detachCompose membuat ulang container dari image baru dan memasang kembali volume yang sama, sehingga data tetap ada. Perbarui client juga. Versi server dan aplikasi sebaiknya tetap berdekatan. Client yang jauh lebih lama daripada server dapat menolak sinkronisasi dan menampilkan pesan ketidakcocokan versi. Buat cadangan sebelum melakukan peningkatan versi utama. Migrasi berjalan saat pertama kali dijalankan, dan tidak ada jalur untuk menurunkan versi.
Hal yang gagal dan yang akan Anda lihat
Aplikasi dimuat, tetapi sinkronisasi tidak pernah selesai. Periksa log akses nginx untuk 413. Itu berarti client_max_body_size disetel terlalu rendah. 502 berarti nginx aktif, tetapi container tidak.
Opsi enkripsi tidak tersedia, atau aplikasi seluler menolak URL tersebut. Halaman tidak berada dalam konteks aman. Bilah alamat akan menampilkan http:// dengan alamat IP atau nama host yang bukan localhost. Perbaiki sertifikat, bukan mencari cara untuk menghindarinya.
Muncul pesan bahwa file anggaran tidak kompatibel dengan versi ini. Versi klien dan server sudah berbeda. Perbarui keduanya ke release yang sama, lalu muat ulang.
Container melakukan restart berulang. Baca docker compose logs actual. Kesalahan izin pada /data berarti direktori yang di-mount tidak dapat ditulisi oleh user container. Kesalahan alamat sedang digunakan berarti ada proses lain yang sudah menggunakan 5006 pada loopback.
Pemuatan pertama terasa lambat. Seluruh file anggaran diunduh ke browser saat Anda membukanya. Ini adalah satu transfer besar, lalu pembacaan lokal. Masalahnya bukan pada kapasitas server, dan menambahkan RAM tidak akan mengubahnya.
FAQ
Apakah Actual Budget memerlukan HTTPS agar dapat digunakan?
Ya, dalam praktiknya. Enkripsi end-to-end Actual menggunakan Web Crypto API pada browser. Browser hanya menyediakan API tersebut dalam konteks aman, yaitu https:// atau http://localhost. Jika diakses melalui HTTP biasa dari mesin lain, fitur tersebut tidak tersedia. Aplikasi seluler resmi juga menolak URL server HTTP biasa. Gunakan sertifikat Let's Encrypt pada hostname nyata, atau sertifikat yang ditandatangani sendiri dengan ACTUAL_HTTPS_KEY dan ACTUAL_HTTPS_CERT jika Anda hanya akan menggunakan browser desktop.
Apakah Actual dapat mengimpor transaksi bank saya secara otomatis?
Hanya melalui layanan pihak ketiga yang Anda daftarkan sendiri: SimpleFIN Bridge di Amerika Utara, Enable Banking di Eropa, Akahu di Selandia Baru, atau Pluggy.ai di Brasil. GoCardless didukung, tetapi tidak menerima akun baru. Kredensial API tersebut tersimpan di server Anda dan tidak dicakup oleh enkripsi end-to-end. Sinkronisasi juga dilakukan secara manual, sehingga Anda menekan tombol dan tidak ada proses yang memeriksa pembaruan di latar belakang. Impor CSV, QIF, OFX, dan QFX tidak memerlukan pihak ketiga sama sekali.
Apa saja yang harus saya cadangkan?
Direktori data yang di-mount, yaitu /opt/actual/data dalam panduan ini. Direktori tersebut berisi server-files/account.sqlite yang menyimpan login dan sesi, serta user-files yang menyimpan file anggaran. Hentikan container sebelum menyalin data, karena menyalin database SQLite yang sedang aktif dapat mengambil penulisan yang belum selesai. Tidak ada data status lain yang tersimpan di server.
Apa yang terjadi jika saya kehilangan password enkripsi?
File tersebut tidak dapat dipulihkan. Password tidak pernah dikirim ke server. Hal ini merupakan tujuan utama enkripsi end-to-end. Karena itu, tidak ada opsi reset atau jalur dukungan untuk memulihkannya. Simpan password di password manager segera setelah membuat file, dan simpan salinannya di lokasi yang tidak bergantung pada server yang sama.
Berapa kapasitas server yang diperlukan Actual Budget?
Sangat kecil. Container menyajikan aset dan file statis. Perhitungan anggaran dilakukan di browser. Satu vCPU bersama dengan RAM 1 GB dapat menjalankannya tanpa masalah. Direktori data untuk anggaran rumah tangga dengan riwayat beberapa tahun biasanya berukuran puluhan megabita. Penggunaan disk terutama disebabkan oleh backup dan container lain, bukan oleh Actual.