اپنے VPS پر Actual Budget کیسے self-host کریں
Docker Compose کے ساتھ Actual Budget چلائیں: data volume، browser کے لیے HTTPS کی وجہ، پہلا budget file، bank imports اور قابل اعتماد backups کی مکمل رہنمائی۔
آپ کیا بنا رہے ہیں
Actual Budget ایک self-hosted envelope budgeting ایپ ہے، اور جب لوگ ایسا YNAB متبادل تلاش کرتے ہیں جسے وہ خود host کر سکیں، تو عموماً یہی جواب ہوتا ہے۔ سرور ایک container، ایک data volume، اور ایک HTTPS نام پر مشتمل ہے۔ عام بجٹ کے لیے درکار ہر چیز سب سے چھوٹے VPS پر بھی آسانی سے چلتی ہے جسے آپ کرائے پر لے سکتے ہیں، کیونکہ سرور زیادہ تر فائلیں محفوظ کرتا ہے اور انہیں sync کرتا ہے۔
کچھ بھی ٹائپ کرنے سے پہلے architecture کو سمجھنا ضروری ہے۔ بجٹ خود ایک SQLite database ہے جو آپ کے browser اور ہر mobile app کے اندر موجود رہتا ہے۔ جس سرور کو آپ ابھی install کرنے والے ہیں، وہ sync endpoint ہے: یہ account list، budget files، اور change log محفوظ رکھتا ہے، جس کی مدد سے phone اور laptop ایک ہی حالت پر متفق رہتے ہیں۔ اسی لیے server down ہونے کے باوجود app کام کرتی رہتی ہے، اور اسی لیے server ضائع ہونے سے آپ کا budget ضائع نہیں ہوتا، بشرطیکہ کسی ایک client کے پاس اس کی copy موجود ہو۔
سرور کو HTTPS کی ضرورت کیوں ہے
Actual کو HTTPS درکار ہے، اور یہ محض رسمی تقاضا نہیں ہے۔ براؤزر Web Crypto API کو، جسے Actual اپنی end-to-end encryption کے لیے استعمال کرتا ہے، صرف اس ماحول میں فراہم کرتے ہیں جسے specification میں secure context کہا جاتا ہے۔ secure context https:// یا http://localhost ہوتا ہے۔ کسی دوسرے machine کے براؤزر میں ایپ کو http://203.0.113.10:5006 سے کھولیں تو یہ خصوصیات موجود نہیں ہوں گی، کیونکہ براؤزر نے انہیں صفحے کے حوالے ہی نہیں کیا۔ سرکاری mobile builds بھی plain http:// server URL کو مسترد کرتی ہیں۔
اس لیے دو قابلِ عمل configurations ہیں۔ container کے سامنے کسی حقیقی name پر حقیقی certificate لگائیں، جیسا کہ یہ guide کرتی ہے۔ یا ACTUAL_HTTPS_KEY اور ACTUAL_HTTPS_CERT کے ذریعے server کو self-signed certificate دیں، جس کا project documentation میں ذکر ہے، اور ہر device پر براؤزر کی warning قبول کریں۔ Let's Encrypt کا مفت certificate پانچ منٹ میں حاصل ہو جاتا ہے، اس لیے پہلا طریقہ اختیار کریں۔
Docker Compose کے ساتھ Actual Budget انسٹال کریں
اگر سرور نیا ہے تو پہلے Docker انسٹال کریں۔ اگر Compose فائل کا syntax آپ کے لیے نیا ہے تو VPS کے لیے Docker Compose کی بنیادی باتیں گائیڈ میں ذیل میں استعمال ہونے والے fields کی وضاحت موجود ہے۔
sudo install -d -m 755 /opt/actual
sudo install -d -m 700 /opt/actual/data/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اس فائل میں تین تفصیلات اہم ہیں۔
image actualbudget/actual-server:latest ہے، جسے project نے Docker Hub پر شائع کیا ہے اور ghcr.io/actualbudget/actual پر mirror کیا گیا ہے۔ کم طاقت والی مشینوں کے لیے latest-alpine tag موجود ہے۔
container ہر چیز /data کے تحت لکھتا ہے۔ اس کے اندر server-files موجود ہے، جس میں آپ کے login اور session tokens رکھنے والی account.sqlite شامل ہے، اور user-files موجود ہے، جس میں budget files خود رکھی جاتی ہیں۔ اس path کو mount کریں، ورنہ اگلا docker compose pull آپ کا budget حذف کر دے گا۔ ACTUAL_DATA_DIR اسے منتقل کر سکتا ہے، لیکن default کافی ہے۔
port صرف 127.0.0.1 پر publish کیا گیا ہے۔ سادہ 5006:5006 ہر interface پر publish کرتا ہے، اور Docker اپنے rules کو ufw سے پہلے لکھتا ہے۔ اس لیے deny-all firewall کے باوجود app انٹرنیٹ پر کھلی ہوگی۔ اس غیر متوقع رویے کی وضاحت Docker کے published ports ufw کو کیوں bypass کرتے ہیں میں موجود ہے۔ loopback پر bind کرنے سے صرف اسی سرور پر موجود reverse proxy اس تک رسائی حاصل کر سکتا ہے۔
اسے شروع کریں:
cd /opt/actual
docker compose up --detach
docker compose logs -f actualجب server بتاتا ہے کہ وہ port 5006 پر listening ہے تو log مستحکم ہو جاتا ہے۔ DNS میں تبدیلی کرنے سے پہلے اسے مقامی طور پر چیک کریں:
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5006/200 کا مطلب ہے کہ app requests فراہم کر رہی ہے۔ curl: (7) Failed to connect کا مطلب ہے کہ container چل نہیں رہا، اور docker compose ps دکھائے گا کہ وہ exit ہو چکا ہے۔ عام وجہ mounted volume میں permission کا مسئلہ ہے، جو log میں EACCES line کے طور پر نظر آتا ہے۔
سرٹیفکیٹ اور حقیقی نام شامل کریں
VPS کی طرف ایک A record پوائنٹ کریں، budget.example.com، اور اس کے resolve ہونے کا انتظار کریں۔ پھر nginx انسٹال کریں اور سرٹیفکیٹ جاری کریں۔ Ubuntu 24.04 پر nginx کے ساتھ Certbot گائیڈ میں سرٹیفکیٹ جاری کرنے اور renewal timer کی مکمل تفصیل موجود ہے۔
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;
}
}client_max_body_size وہ لائن ہے جسے لوگ اکثر بھول جاتے ہیں۔ مکمل sync کے دوران budget فائل پوری کی پوری upload ہوتی ہے۔ Nginx میں request body کی ڈیفالٹ حد 1 MB ہے۔ اس لیے فائل اس حد سے بڑی ہوتے ہی sync ناکام ہو جاتا ہے۔ nginx access log میں 413 Request Entity Too Large دکھائی دیتا ہے، جبکہ app صرف ایک عمومی sync error دکھاتی ہے۔ سرور کی اپنی الگ حدود ہیں: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB کی ڈیفالٹ قدر 20 اور ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB کی ڈیفالٹ قدر 50 ہے۔ اس لیے nginx کی حد ان میں سے آپ پر لاگو ہونے والی حد سے زیادہ مقرر کریں۔
Reload کریں اور ٹیسٹ کریں:
sudo nginx -t && sudo systemctl reload nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://budget.example.com/پہلی بار چلانا: پاس ورڈ اور آپ کی پہلی بجٹ فائل
https://budget.example.com کو browser میں کھولیں۔ پہلی screen آپ سے server password مقرر کرنے کو کہتی ہے۔ یہ واحد password پورے server کی حفاظت کرتا ہے، اس لیے ایک طویل random password بنائیں اور اسے ایسی جگہ محفوظ رکھیں جہاں آپ اسے دوبارہ تلاش کر سکیں، مثلاً خود میزبانی والا Vaultwarden password manager۔ کوئی user accounts بنانے کی ضرورت نہیں۔ Actual کا server ڈیزائن کے لحاظ سے single-password ہے، اس لیے budget شیئر کرنے کا مطلب یہی password شیئر کرنا ہے۔
اس کے بعد budget file بنائیں۔ Actual پوچھتا ہے کہ کیا end-to-end encryption فعال کرنی ہے۔ yes منتخب کریں۔ اس طرح server صرف ciphertext محفوظ کرے گا، جو کرائے کی machine پر مالی data کے لیے درست انتخاب ہے۔ اس کی حقیقی قیمت بھی ہے: encryption password کبھی server تک نہیں پہنچتا۔ اگر آپ اسے کھو دیں تو file بھی ختم ہو جاتی ہے اور اسے reset کرنے کا کوئی طریقہ نہیں ہے۔ اس screen سے آگے بڑھنے کے لیے click کرنے سے پہلے اسے لکھ لیں۔
اپنے starting balances بینک کے موجودہ اعداد و شمار کے مطابق مقرر کریں، برسوں کی history import کرنے کے بجائے۔ Envelope budgeting آپ کے پاس موجود موجودہ رقم سے آگے کا حساب کرتا ہے، اس لیے خالی history سے آپ کو کوئی نقصان نہیں ہوگا۔
لین دین درآمد کرنا
یہاں جوش سے زیادہ دیانت داری اہم ہے، کیونکہ درآمد کا طریقہ وہ بنیادی وجہ ہے جس کی بنا پر لوگ self-hosted budgeting سے دست بردار ہو جاتے ہیں۔
دستی اندراج بنیادی طریقہ ہے اور یہ ہمیشہ کام کرتا ہے۔ envelope method میں یہ بلاشبہ اس کا مقصد بھی ہے، کیونکہ خریداری ٹائپ کرنے سے آپ کو اپنے خرچ کا احساس ہوتا ہے۔
فائل درآمد زیادہ تر کام سنبھال لیتی ہے۔ Actual، CSV، QIF، OFX اور QFX پڑھتا ہے، اور ہر بینک کم از کم ان میں سے ایک فارمیٹ میں فائل برآمد کرتا ہے۔ account screen سے ہر account کی درآمد کریں، columns کی mapping ایک بار کریں، اور Actual اس account کے لیے وہ layout محفوظ رکھتا ہے۔
خودکار بینک sync موجود ہے، لیکن اس کے لیے third-party service درکار ہوتی ہے، کیونکہ server خود بینکوں سے رابطہ نہیں کر سکتا۔ Actual شمالی امریکا کے بینکوں کے لیے SimpleFIN Bridge، یورپ کے لیے Enable Banking، نیوزی لینڈ کے لیے Akahu، اور برازیل کے لیے Pluggy.ai کو support کرتا ہے۔ GoCardless اب بھی supported ہے، لیکن نئے accounts قبول نہیں کر رہا۔ آپ provider کے ساتھ خود sign up کرتے ہیں، credentials بناتے ہیں، اور انہیں server میں شامل کرتے ہیں۔ July 2026 کے مطابق SimpleFIN Bridge، 25 institutions تک کے لیے سالانہ 15 US dollars وصول کرتا ہے، جبکہ دیگر providers کی قیمتیں مختلف ہیں۔
اس پر انحصار کرنے سے پہلے دو حدود تسلیم کریں۔ API credentials server پر موجود رہتے ہیں اور end-to-end encryption کے تحت محفوظ نہیں ہوتے، کیونکہ server کو انہیں استعمال کرنا ہوتا ہے۔ Actual polling نہیں کرتا: sync ایک ایسا button ہے جسے آپ دباتے ہیں، یہ background job نہیں ہے۔
بیک اپ، کیونکہ یہ صرف فائلیں ہیں
آپ کے لیے اہم ہر چیز /opt/actual/data کے اندر موجود ہے۔ کوئی export مرحلہ نہیں ہے، اور نہ ہی script کے لیے database dump درکار ہے۔
واحد مسئلہ SQLite ہے۔ سرور کے اس میں لکھتے وقت account.sqlite کو copy کرنے سے نامکمل transaction محفوظ ہو سکتا ہے، اور اس کا پتا restore کی کوشش تک نہیں چلتا۔ copy مکمل ہونے میں لگنے والے چند سیکنڈ کے لیے container روک دیں:
cd /opt/actual
docker compose stop
restic -r sftp:backup@backup.example.com:/srv/restic backup /opt/actual/data
docker compose startاسے VPS پر restic backups میں بیان کردہ طریقے کے مطابق schedule پر چلائیں۔ اس طریقے میں repository setup، retention اور restore drill شامل ہیں۔ restore drill چلائیں۔ جس backup کو آپ نے کبھی restore نہ کیا ہو، وہ صرف ایک اندازہ ہے۔
Actual کے اپنے client-side backups الگ نوعیت کے ہیں اور ان کے بارے میں جاننا مفید ہے۔ browser budget file کی حالیہ copies محفوظ رکھتا ہے، جن تک file menu سے رسائی حاصل کی جا سکتی ہے۔ اس سے "میں نے غلطی سے کوئی category حذف کر دی" جیسے مسئلے کو سرور کو چھوئے بغیر حل کیا جا سکتا ہے۔
سرور کو اپ ڈیٹ کرنا
cd /opt/actual
docker compose pull
docker compose up --detachCompose نئے image سے container دوبارہ بناتا ہے اور اسی volume کو دوبارہ منسلک کرتا ہے، اس لیے ڈیٹا برقرار رہتا ہے۔ clients کو بھی اپ ڈیٹ کریں۔ سرور اور app کے ورژنز کا قریب قریب ہونا ضروری ہے، اور سرور سے بہت پرانا client ورژن کے عدم مطابقت کے پیغام کے ساتھ sync کرنے سے انکار کر سکتا ہے۔ major version میں بڑی تبدیلی سے پہلے backup لیں، کیونکہ migration پہلی بار start ہونے پر چلتی ہے اور downgrade کا کوئی راستہ نہیں ہوتا۔
کیا خراب ہوتا ہے اور آپ کو کیا نظر آئے گا
ایپ لوڈ ہو جاتی ہے، لیکن sync کبھی مکمل نہیں ہوتا۔ 413 کے لیے nginx access log چیک کریں۔ اس کا مطلب ہے کہ client_max_body_size بہت کم مقرر ہے۔ اس کے برعکس 502 کا مطلب ہے کہ nginx چل رہا ہے، لیکن container نہیں چل رہا۔
Encryption کے اختیارات موجود نہیں، یا mobile app URL قبول نہیں کرتی۔ صفحہ secure context میں نہیں ہے۔ address bar میں http:// کے ساتھ IP address یا ایسا hostname دکھائی دے گا جو localhost نہیں ہے۔ اس مسئلے کا workaround کرنے کے بجائے certificate درست کریں۔
یہ پیغام دکھائی دیتا ہے کہ budget file اس version کے ساتھ compatible نہیں ہے۔ Client اور server کے versions میں فرق آ گیا ہے۔ دونوں کو ایک ہی release پر update کریں اور دوبارہ load کریں۔
Container بار بار restart ہوتا ہے۔ docker compose logs actual پڑھیں۔ /data پر permission error کا مطلب ہے کہ mounted directory container کے user کے لیے writable نہیں ہے۔ address-in-use error کا مطلب ہے کہ کوئی اور چیز پہلے ہی loopback پر 5006 استعمال کر رہی ہے۔
پہلی بار load ہونے میں وقت لگتا ہے۔ جب آپ اسے کھولتے ہیں تو پوری budget file browser پر download ہوتی ہے۔ پہلے ایک بڑا transfer ہوتا ہے، پھر local reads ہوتی ہیں۔ یہ server sizing کا مسئلہ نہیں ہے، اور RAM بڑھانے سے اس میں تبدیلی نہیں آئے گی۔
FAQ
کیا Actual Budget کو کام کرنے کے لیے HTTPS درکار ہے؟
عملی طور پر ہاں۔ Actual کی end-to-end encryption براؤزر کے Web Crypto API پر منحصر ہے، اور براؤزر اسے صرف secure context میں فراہم کرتے ہیں، یعنی https:// یا http://localhost۔ کسی دوسری مشین سے سادہ HTTP استعمال کرنے پر یہ خصوصیات دستیاب نہیں ہوتیں، اور سرکاری موبائل apps سادہ HTTP server URL کو مسترد کر دیتی ہیں۔ حقیقی hostname پر Let's Encrypt certificate استعمال کریں، یا اگر آپ صرف desktop browser استعمال کرتے ہیں تو ACTUAL_HTTPS_KEY اور ACTUAL_HTTPS_CERT کے ساتھ self-signed certificate استعمال کریں۔
کیا Actual میرے بینک کے لین دین خودکار طور پر import کر سکتا ہے؟
صرف کسی third-party service کے ذریعے، جس کے لیے آپ خود sign up کرتے ہیں: North America میں SimpleFIN Bridge، Europe میں Enable Banking، New Zealand میں Akahu، یا Brazil میں Pluggy.ai۔ GoCardless supported ہے، لیکن یہ نئے accounts قبول نہیں کر رہا۔ ان API credentials کو آپ کے server پر رکھا جاتا ہے اور end-to-end encryption ان کا احاطہ نہیں کرتی۔ Sync بھی manual ہے، اس لیے آپ ایک button دباتے ہیں اور پس منظر میں کوئی polling نہیں ہوتی۔ CSV، QIF، OFX اور QFX import کے لیے کسی third party کی ضرورت نہیں۔
مجھے بالکل کن چیزوں کا backup لینا ہوگا؟
Mounted data directory کا، جو اس guide میں /opt/actual/data ہے۔ اس میں logins اور sessions کے ساتھ server-files/account.sqlite، اور budget files کے ساتھ user-files شامل ہے۔ Copy کرنے سے پہلے container کو stop کریں، کیونکہ live SQLite database کی copy میں نامکمل write شامل ہو سکتی ہے۔ Server پر کوئی اور چیز state محفوظ نہیں رکھتی۔
اگر encryption password کھو دوں تو کیا ہوگا؟
File recover نہیں کی جا سکتی۔ Password کبھی server تک نہیں پہنچتا، اور یہی end-to-end encryption کا بنیادی مقصد ہے۔ اس لیے نہ reset ممکن ہے اور نہ support کے ذریعے بحالی۔ File بناتے ہی اسے password manager میں محفوظ کریں، اور ایک copy ایسی جگہ رکھیں جو اسی server پر منحصر نہ ہو۔
Actual Budget کو کتنے server وسائل درکار ہیں؟
بہت کم۔ Container static assets اور files فراہم کرتا ہے، جبکہ budget calculations browser میں ہوتی ہیں۔ 1 GB RAM والا ایک shared vCPU اسے آسانی سے چلا لیتا ہے، اور کئی سال کی history والے household budget کی data directory کا حجم عموماً دسیوں megabytes رہتا ہے۔ Disk pressure آپ کے backups اور دوسرے containers کی وجہ سے آتا ہے، Actual کی وجہ سے نہیں۔