SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-27

Cara Host Actual Budget Sendiri di VPS Menggunakan Docker

Ketahui cara memasang Actual Budget di VPS dengan Docker Compose. Panduan ini merangkumi konfigurasi volum data, keperluan HTTPS, import bank, dan strategi sandaran data.

Apa yang anda sedang bina

Actual Budget ialah aplikasi belanjawan berasaskan sampul yang boleh dihoskan sendiri, dan ia merupakan jawapan lazim apabila pengguna mencari alternatif YNAB yang boleh dihoskan sendiri. Pelayan ini terdiri daripada satu kontena, satu volum data, dan satu nama HTTPS. Segala keperluan belanjawan biasa boleh berjalan dengan lancar pada VPS terkecil yang boleh anda sewa, kerana pelayan tersebut kebanyakannya hanya menyimpan fail dan menyegerakkannya.

Seni bina ini perlu difahami sebelum anda menaip apa-apa. Belanjawan itu sendiri merupakan pangkalan data SQLite yang berada di dalam pelayar anda dan di dalam setiap aplikasi mudah alih. Pelayan yang bakal anda pasang ialah titik akhir penyegerakan: ia menyimpan senarai akaun, fail belanjawan, dan log perubahan yang membolehkan telefon serta komputer riba menyelaraskan data. Itulah sebabnya aplikasi ini masih berfungsi apabila pelayan tergendala, dan itulah sebabnya kehilangan pelayan tidak akan menyebabkan belanjawan anda hilang selagi satu klien masih menyimpan salinannya.

Mengapa pelayan memerlukan HTTPS

Actual memerlukan HTTPS, dan ini bukan sekadar formaliti. Pelayar hanya mendedahkan Web Crypto API, iaitu antara muka yang digunakan oleh Actual untuk penyulitan hujung-ke-hujung (end-to-end encryption), dalam apa yang dipanggil oleh spesifikasi sebagai konteks selamat (secure context). Konteks selamat ialah https:// atau http://localhost. Muatkan aplikasi daripada http://203.0.113.10:5006 dalam pelayar pada mesin lain dan ciri-ciri tersebut tidak akan tersedia, kerana pelayar tidak pernah memberikannya kepada halaman tersebut. Binaan mudah alih rasmi juga menolak URL pelayan http:// biasa.

Oleh itu, terdapat dua persediaan yang boleh digunakan. Letakkan sijil sebenar pada nama domain sebenar di hadapan kontena, yang merupakan perkara yang dilakukan oleh panduan ini. Atau, berikan pelayan sijil yang ditandatangani sendiri (self-signed certificate) dengan ACTUAL_HTTPS_KEY dan ACTUAL_HTTPS_CERT, seperti yang didokumentasikan oleh projek tersebut, dan terima amaran pelayar pada setiap peranti. Sijil percuma daripada Let's Encrypt hanya mengambil masa lima minit, jadi pilihlah pilihan pertama.

Memasang Actual Budget dengan Docker Compose

Pasang Docker terlebih dahulu jika pelayan masih baharu. Jika sintaks fail Compose masih baharu bagi anda, panduan asas Docker Compose untuk VPS merangkumi medan yang digunakan di bawah.

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

Tulis /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

Tiga perincian dalam fail tersebut adalah penting.

Imejnya ialah actualbudget/actual-server:latest, yang diterbitkan oleh projek tersebut ke Docker Hub dan dicerminkan di ghcr.io/actualbudget/actual. Terdapat tag latest-alpine untuk mesin berkuasa rendah.

Kontena tersebut menulis segala-galanya di bawah /data. Di dalamnya anda akan mendapat server-files, yang menyimpan account.sqlite dengan token log masuk dan sesi anda, serta user-files, yang menyimpan fail belanjawan itu sendiri. Lekapkan (mount) laluan tersebut atau docker compose pull yang seterusnya akan memadamkan belanjawan anda. ACTUAL_DATA_DIR boleh memindahkannya, tetapi tetapan lalai sudah memadai.

Port diterbitkan pada 127.0.0.1 sahaja. 5006:5006 kosong akan menerbitkan pada setiap antara muka, dan Docker menulis peraturannya sendiri mendahului ufw, jadi aplikasi tersebut akan terdedah kepada internet walaupun dengan firewall deny-all. Kejutan tersebut dijelaskan dalam mengapa port yang diterbitkan Docker memintas ufw. Mengikat kepada loopback bermakna hanya reverse proxy pada mesin yang sama boleh mencapainya.

Mulakannya:

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

Log akan menjadi stabil sebaik sahaja pelayan melaporkan ia sedang mendengar pada port 5006. Semak secara setempat sebelum anda menyentuh DNS:

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

200 bermakna aplikasi sedang beroperasi. curl: (7) Failed to connect bermakna kontena tidak berjalan, dan docker compose ps akan menunjukkan ia telah keluar (exited). Punca biasa ialah masalah kebenaran (permission) pada volum yang dilekapkan, yang boleh dilihat sebagai baris EACCES dalam log.

Letakkan sijil dan nama sebenar di hadapan

Halakan rekod A ke VPS, budget.example.com, dan tunggu sehingga ia selesai diselesaikan (resolve). Kemudian, pasang nginx dan keluarkan sijil tersebut. Panduan Certbot pada Ubuntu 24.04 dengan nginx merangkumi proses pengeluaran dan pemasa pembaharuan sepenuhnya.

Blok proksi:

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 ialah baris yang sering dilupakan oleh pengguna. Fail bajet dimuat naik sepenuhnya semasa penyelarasan penuh (full sync). Nginx menetapkan had badan permintaan (request body) lalai kepada 1 MB, jadi apabila saiz fail melebihi had tersebut, penyelarasan akan gagal dengan 413 Request Entity Too Large dalam log akses nginx, manakala aplikasi hanya memaparkan ralat penyelarasan umum. Pelayan mempunyai hadnya yang tersendiri: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB secara lalai ialah 20 dan ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB secara lalai ialah 50, jadi tetapkan had nginx melebihi nilai yang berkenaan dengan anda.

Muat semula dan uji:

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

Jalankan kali pertama: kata laluan dan fail belanjawan pertama anda

Buka https://budget.example.com dalam pelayar web. Skrin pertama meminta anda menetapkan kata laluan pelayan. Kata laluan tunggal itu melindungi keseluruhan pelayan, jadi jana kata laluan rawak yang panjang dan simpan di tempat yang boleh anda temui semula, seperti pengurus kata laluan Vaultwarden yang dihoskan sendiri. Tiada akaun pengguna untuk dicipta. Pelayan Actual direka dengan kata laluan tunggal, jadi berkongsi belanjawan bermakna berkongsi kata laluan tersebut.

Kemudian, cipta fail belanjawan. Actual akan bertanya sama ada anda mahu mendayakan penyulitan hujung-ke-hujung (end-to-end encryption). Pilih ya supaya pelayan hanya menyimpan teks sifer (ciphertext), yang merupakan pilihan tepat untuk data kewangan pada mesin sewaan. Kosnya nyata: kata laluan penyulitan tidak pernah sampai ke pelayan, jadi jika anda kehilangannya, fail tersebut akan hilang dan tiada cara untuk menetapkan semula. Tulis kata laluan tersebut sebelum anda meneruskan skrin itu.

Tetapkan baki permulaan anda berdasarkan angka semasa bank anda dan bukannya mengimport sejarah selama bertahun-tahun. Belanjawan sampul (envelope budgeting) berfungsi ke hadapan berdasarkan wang yang anda miliki sekarang, jadi ketiadaan sejarah tidak menjejaskan anda.

Memasukkan transaksi

Di sinilah kejujuran lebih penting daripada semangat, kerana proses import adalah sebab utama pengguna berhenti menggunakan sistem belanjawan yang dihoskan sendiri (self-hosted).

Kemasukan manual adalah asas dan ia sentiasa berfungsi. Bagi kaedah sampul surat, ini boleh dikatakan sebagai tujuan utamanya, kerana menaip setiap pembelian adalah perkara yang membuatkan anda menyedarinya.

Import fail mengendalikan transaksi pukal. Actual membaca format CSV, QIF, OFX dan QFX, dan setiap bank mengeksport sekurang-kurangnya satu daripada format tersebut. Lakukan import bagi setiap akaun daripada skrin akaun, petakan lajur sekali sahaja, dan Actual akan mengingati susun atur tersebut untuk akaun berkenaan.

Penyelarasan bank automatik tersedia, dan ia memerlukan perkhidmatan pihak ketiga kerana pelayan tidak boleh berhubung dengan bank secara sendiri. Actual menyokong SimpleFIN Bridge untuk bank di Amerika Utara, Enable Banking untuk Eropah, Akahu untuk New Zealand, dan Pluggy.ai untuk Brazil. GoCardless masih disokong tetapi tidak lagi menerima akaun baharu. Anda perlu mendaftar dengan penyedia tersebut sendiri, menjana kelayakan, dan menambahkannya ke pelayan. SimpleFIN Bridge mengenakan bayaran 15 US dollars setahun untuk sehingga 25 institusi setakat Julai 2026, dan penyedia lain mempunyai harga yang berbeza.

Terdapat dua had yang perlu diterima sebelum anda bergantung pada ciri ini. Kelayakan API disimpan pada pelayan dan tidak dilindungi oleh penyulitan hujung-ke-hujung (end-to-end encryption), kerana pelayan perlu menggunakannya. Selain itu, Actual tidak melakukan pengundian (polling): penyelarasan adalah butang yang perlu anda tekan, bukannya tugasan latar belakang.

Sandaran, kerana ia hanyalah fail

Segala data yang penting bagi anda berada di bawah /opt/actual/data. Tiada langkah eksport dan tiada dump pangkalan data yang perlu diskripkan.

Satu perangkap yang perlu dielakkan ialah SQLite. Menyalin account.sqlite semasa pelayan sedang menulis kepadanya boleh menyebabkan transaksi yang tidak lengkap disalin, dan anda tidak akan menyedarinya sehingga anda cuba melakukan pemulihan. Hentikan kontena untuk beberapa saat sementara proses penyalinan berlangsung:

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

Jadualkan proses ini menggunakan pendekatan dalam sandaran restic pada VPS, yang merangkumi penyediaan repositori, pengekalan dan latihan pemulihan. Lakukan latihan pemulihan tersebut. Sandaran yang tidak pernah dipulihkan hanyalah satu andaian.

Sandaran bahagian klien (client-side) milik Actual adalah perkara berasingan dan perlu diketahui. Pelayar menyimpan salinan terkini fail belanjawan, yang boleh dicapai daripada menu fail. Ini meliputi situasi "Saya tersilap memadam kategori" tanpa perlu menyentuh pelayan langsung.

Mengemas kini pelayan

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

Compose mencipta semula bekas daripada imej baharu dan menyambungkan semula volum yang sama, jadi data kekal tersedia. Kemas kini klien juga. Versi pelayan dan aplikasi sepatutnya kekal hampir sama. Klien yang jauh lebih lama daripada pelayan mungkin enggan menyegerak dan memaparkan mesej ketidakpadanan versi. Buat sandaran sebelum melangkau ke versi utama yang lebih baharu kerana migrasi dijalankan pada permulaan pertama dan tiada laluan penurunan versi. Actual tidak terlalu bermasalah dengan tag latest yang terapung kerana keadaannya terdiri daripada direktori fail. Namun, aplikasi yang menggunakan pangkalan data sebenar tidak begitu mudah dikendalikan. mengehos sendiri Chatwoot menerangkan tag yang dipakukan serta pembuangan pangkalan data sebelum naik taraf yang diperlukan dalam amalan tersebut.

Apa yang rosak, dan apa yang akan anda lihat

Aplikasi dimuatkan tetapi penyelarasan tidak pernah selesai. Semak log akses nginx untuk 413. Itu bermakna client_max_body_size ditetapkan terlalu rendah. 502 pula bermakna nginx sedang berjalan tetapi kontena tidak.

Pilihan penyulitan tiada, atau aplikasi mudah alih menolak URL tersebut. Halaman tersebut tidak berada dalam konteks yang selamat. Bar alamat akan memaparkan http:// dengan alamat IP atau nama hos yang bukan localhost. Betulkan sijil tersebut daripada mencari jalan penyelesaian sementara.

Mesej menyatakan fail belanjawan tidak serasi dengan versi ini. Versi klien dan pelayan telah menjadi tidak selari. Kemas kini kedua-duanya kepada keluaran yang sama dan muat semula.

Kontena dimulakan semula secara berulang. Baca docker compose logs actual. Ralat kebenaran pada /data bermakna direktori yang dipasang tidak boleh ditulis oleh pengguna kontena tersebut. Ralat alamat-sedang-digunakan bermakna ada proses lain yang sudah menggunakan port 5006 pada loopback.

Muatan pertama terasa perlahan. Keseluruhan fail belanjawan dimuat turun ke pelayar apabila anda membukanya. Itu adalah satu pemindahan data yang besar, kemudian bacaan dilakukan secara setempat. Ini bukan masalah saiz pelayan, dan menambah RAM tidak akan mengubahnya.

FAQ

Adakah Actual Budget memerlukan HTTPS untuk berfungsi?

Ya, secara praktikalnya. Penyulitan hujung-ke-hujung (end-to-end encryption) Actual menggunakan Web Crypto API pelayar, dan pelayar hanya mendedahkan fungsi tersebut dalam konteks selamat, iaitu https:// atau http://localhost. Melalui HTTP biasa daripada mesin lain, ciri tersebut tidak tersedia, dan aplikasi mudah alih rasmi akan menolak URL pelayan HTTP biasa. Gunakan sijil Let’s Encrypt pada hostname sebenar, atau sijil yang ditandatangani sendiri (self-signed) dengan ACTUAL_HTTPS_KEY dan ACTUAL_HTTPS_CERT jika anda hanya menggunakan pelayar desktop.

Bolehkah Actual mengimport transaksi bank saya secara automatik?

Hanya melalui perkhidmatan pihak ketiga yang anda daftar sendiri: SimpleFIN Bridge di Amerika Utara, Enable Banking di Eropah, Akahu di New Zealand, atau Pluggy.ai di Brazil. GoCardless disokong tetapi tidak lagi menerima akaun baharu. Kredensial API tersebut disimpan pada pelayan anda dan tidak dilindungi oleh penyulitan hujung-ke-hujung. Penyegerakan juga dilakukan secara manual, jadi anda perlu menekan butang dan tiada proses yang meninjau (poll) di latar belakang. Import CSV, QIF, OFX dan QFX tidak memerlukan sebarang pihak ketiga.

Apakah yang perlu saya sandarkan (backup) sebenarnya?

Direktori data yang dilekapkan (mounted), iaitu /opt/actual/data dalam panduan ini. Ia mengandungi server-files/account.sqlite dengan log masuk dan sesi, serta user-files dengan fail belanjawan. Hentikan container sebelum menyalin, kerana menyalin pangkalan data SQLite yang sedang aktif boleh menyebabkan penulisan separa (partial write). Tiada perkara lain pada pelayan yang menyimpan status (state).

Apakah yang berlaku jika saya kehilangan kata laluan penyulitan?

Fail tersebut tidak dapat dipulihkan. Kata laluan tidak pernah sampai ke pelayan, itulah tujuan utama penyulitan hujung-ke-hujung, jadi tiada tetapan semula dan tiada saluran sokongan. Simpan kata laluan dalam pengurus kata laluan sebaik sahaja anda mencipta fail tersebut, dan simpan salinan di tempat yang tidak bergantung pada pelayan yang sama.

Berapakah spesifikasi pelayan yang diperlukan oleh Actual Budget?

Sangat sedikit. Container ini menghidangkan aset statik dan fail, manakala pengiraan belanjawan berlaku di dalam pelayar. Satu vCPU kongsi dengan 1 GB RAM sudah memadai untuk menjalankannya tanpa masalah, dan direktori data untuk belanjawan isi rumah dengan sejarah beberapa tahun hanya bersaiz puluhan megabait. Tekanan cakera datang daripada sandaran anda dan container lain, bukan daripada Actual. Jika anda sedang memilih spesifikasi pelayan yang perlu menjalankan aplikasi lebih berat di sampingnya, pelayan foto biasanya menjadi penentu, jadi semak berapa banyak RAM yang sebenarnya diperlukan oleh PhotoPrism dan Immich sebelum anda memilih pelan.