SSD Nodes Learn Hosting plans →
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-27

اپنے VPS پر Actual Budget کیسے host کریں

Docker Compose سے VPS پر Actual Budget چلائیں: data volume محفوظ کریں، HTTPS کی browser شرط سمجھیں، پہلا budget بنائیں، bank imports اور backups ترتیب دیں۔

آپ کیا بنا رہے ہیں

Actual Budget ایک self-hosted envelope budgeting ایپ ہے۔ جب لوگ ایسا YNAB متبادل تلاش کرتے ہیں جسے وہ خود host کر سکیں، تو عموماً یہی انتخاب کرتے ہیں۔ سرور میں ایک container، ایک data volume اور ایک HTTPS نام ہوتا ہے۔ عام بجٹ کے لیے درکار تمام سہولیات سب سے چھوٹے VPS پر بھی آسانی سے چلتی ہیں، کیونکہ سرور زیادہ تر files محفوظ کرتا اور انہیں sync کرتا ہے۔

کسی بھی command کو چلانے سے پہلے architecture کو سمجھنا ضروری ہے۔ اصل budget ایک SQLite database ہے جو آپ کے browser اور ہر mobile app کے اندر موجود رہتا ہے۔ آپ جو server install کرنے والے ہیں، وہ sync endpoint ہے۔ یہ account list، budget files اور change log محفوظ رکھتا ہے، جس کی مدد سے phone اور laptop ایک ہی حالت پر متفق رہتے ہیں۔ اسی وجہ سے server down ہونے پر بھی app کام کرتی رہتی ہے۔ اور اگر کسی ایک client کے پاس copy موجود ہو، تو server ضائع ہونے سے آپ کا budget ضائع نہیں ہوتا۔

سرور کو HTTPS کی ضرورت کیوں ہے

Actual کو HTTPS درکار ہے، اور یہ محض رسمی تقاضا نہیں ہے۔ Browsers صرف Web Crypto API فراہم کرتے ہیں، جسے Actual اپنی end-to-end encryption کے لیے استعمال کرتا ہے، اس context میں جسے specification secure context کہتی ہے۔ Secure context https:// یا http://localhost ہوتا ہے۔ کسی دوسرے machine پر موجود browser میں ایپ کو http://203.0.113.10:5006 سے کھولیں تو یہ features موجود نہیں ہوں گے، کیونکہ browser نے انہیں page کے حوالے ہی نہیں کیا۔ Official mobile builds بھی plain http:// server URL کو مسترد کرتی ہیں۔

اس لیے 2 قابلِ عمل configurations ہیں۔ Container کے سامنے کسی حقیقی نام پر حقیقی certificate لگائیں، جیسا کہ یہ guide کرتی ہے۔ یا ACTUAL_HTTPS_KEY اور ACTUAL_HTTPS_CERT کے ذریعے server کو self-signed certificate دیں، جس کا project documentation موجود ہے، اور ہر device پر browser warning قبول کریں۔ Let's Encrypt کا free certificate 5 منٹ میں حاصل ہو جاتا ہے، اس لیے پہلا option اختیار کریں۔

Docker Compose کے ساتھ Actual Budget انسٹال کریں

اگر سرور نیا ہے تو پہلے Docker انسٹال کریں۔ اگر Compose file 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

اس file میں تین تفصیلات اہم ہیں۔

image actualbudget/actual-server:latest ہے، جسے project نے Docker Hub پر شائع کیا ہے اور ghcr.io/actualbudget/actual پر mirror کیا گیا ہے۔ کم توانائی استعمال کرنے والی machines کے لیے latest-alpine tag موجود ہے۔

container تمام data /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 پر port publish کرتا ہے، اور Docker اپنے rules کو ufw سے پہلے لاگو کرتا ہے۔ اس لیے deny-all firewall کے باوجود app internet پر کھلی رہتی۔ اس غیر متوقع رویے کی وضاحت Docker کے published ports ufw کو bypass کیوں کرتے ہیں میں موجود ہے۔ loopback پر bind کرنے سے صرف اسی server پر موجود reverse proxy اس تک پہنچ سکتا ہے۔

اسے start کریں:

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

جب server یہ بتائے کہ وہ port 5006 پر listening کر رہا ہے تو log معمول پر آ جاتا ہے۔ DNS تبدیل کرنے سے پہلے اسے مقامی طور پر check کریں:

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

200 کا مطلب ہے کہ app requests serve کر رہی ہے۔ curl: (7) Failed to connect کا مطلب ہے کہ container چل نہیں رہا، اور docker compose ps دکھائے گا کہ وہ exit ہو چکا ہے۔ عام وجہ mounted volume پر permission کا مسئلہ ہوتی ہے، جو log میں EACCES line کے طور پر نظر آتا ہے۔

سامنے certificate اور حقیقی نام شامل کریں

VPS کی طرف A record، budget.example.com، point کریں اور اس کے resolve ہونے کا انتظار کریں۔ پھر nginx انسٹال کریں اور certificate جاری کریں۔ Ubuntu 24.04 پر nginx کے ساتھ Certbot گائیڈ میں certificate جاری کرنے اور 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 وہ line ہے جسے لوگ اکثر بھول جاتے ہیں۔ مکمل sync کے دوران budget file پوری upload ہوتی ہے۔ nginx میں request body کی default حد 1 MB ہے۔ اس لیے جب file اس حد سے بڑی ہو جائے تو sync ناکام ہو جاتا ہے۔ nginx access log میں 413 Request Entity Too Large ظاہر ہوتا ہے، جبکہ app صرف عمومی sync error دکھاتی ہے۔ Server کی اپنی الگ limits ہیں: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB کی default قدر 20 اور ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB کی default قدر 50 ہے۔ اس لیے nginx کی limit ان میں سے آپ پر لاگو ہونے والی قدر سے زیادہ مقرر کریں۔

Reload کریں اور test کریں:

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

پہلی بار چلانا: پاس ورڈ اور پہلی بجٹ فائل

براؤزر میں https://budget.example.com کھولیں۔ پہلی اسکرین پر آپ سے server password مقرر کرنے کو کہا جائے گا۔ یہ ایک ہی پاس ورڈ پورے server کی حفاظت کرتا ہے، اس لیے ایک لمبا اور random پاس ورڈ بنائیں اور اسے ایسی جگہ محفوظ رکھیں جہاں آپ اسے دوبارہ تلاش کر سکیں، مثلاً خود میزبانی والا Vaultwarden password manager۔ کوئی user accounts بنانے کی ضرورت نہیں۔ Actual کا server single-password ڈیزائن استعمال کرتا ہے، اس لیے budget شیئر کرنے کا مطلب یہی پاس ورڈ شیئر کرنا ہے۔

اس کے بعد ایک budget file بنائیں۔ Actual پوچھے گا کہ کیا end-to-end encryption فعال کرنی ہے۔ yes منتخب کریں۔ اس طرح server صرف ciphertext محفوظ کرے گا، جو کرائے کی machine پر مالی data کے لیے درست انتخاب ہے۔ اس کی حقیقی قیمت بھی ہے: encryption password server تک نہیں پہنچتا۔ اگر آپ اسے کھو دیں تو file بھی ختم ہو جائے گی اور اسے reset کرنے کا کوئی طریقہ موجود نہیں۔ اس اسکرین سے آگے بڑھنے سے پہلے اسے لکھ کر محفوظ کر لیں۔

اپنے starting balances بینک کے موجودہ figures کے مطابق مقرر کریں، کئی سال کی history import نہ کریں۔ Envelope budgeting آپ کے موجودہ پیسوں سے آگے کا حساب چلاتی ہے، اس لیے خالی history رکھنے سے آپ کا کچھ نقصان نہیں ہوتا۔

لین دین حاصل کرنا

یہاں جوش سے زیادہ دیانت داری اہم ہے، کیونکہ import کا طریقہ وہ بنیادی وجہ ہے جس کے باعث لوگ self-hosted budgeting سے دور ہو جاتے ہیں۔

دستی اندراج بنیادی طریقہ ہے اور یہ ہمیشہ کام کرتا ہے۔ envelope method میں یہی اصل مقصد بھی ہو سکتا ہے، کیونکہ خریداری ٹائپ کرنے سے آپ اس پر توجہ دیتے ہیں۔

File import زیادہ تر لین دین سنبھال لیتا ہے۔ Actual، CSV، QIF، OFX اور QFX پڑھتا ہے، اور ہر bank کم از کم ان میں سے ایک format export کرتا ہے۔ account screen سے ہر account کا import کریں، columns کو ایک بار map کریں، اور Actual اس account کے لیے وہ layout یاد رکھے گا۔

Automatic bank sync موجود ہے، لیکن اس کے لیے third-party service درکار ہوتی ہے، کیونکہ server خود banks سے رابطہ نہیں کر سکتا۔ Actual شمالی امریکا کے banks کے لیے SimpleFIN Bridge، یورپ کے لیے Enable Banking، New Zealand کے لیے Akahu، اور Brazil کے لیے Pluggy.ai کو support کرتا ہے۔ GoCardless اب بھی supported ہے، لیکن یہ نئے accounts قبول نہیں کر رہا۔ آپ خود provider کے ساتھ sign up کرتے ہیں، credentials generate کرتے ہیں، اور انہیں server میں شامل کرتے ہیں۔ July 2026 تک SimpleFIN Bridge، زیادہ سے زیادہ 25 institutions کے لیے، ہر سال 15 US dollars وصول کرتا ہے؛ باقی providers کی pricing مختلف ہے۔

اس پر انحصار کرنے سے پہلے دو حدود تسلیم کریں۔ API credentials server پر موجود رہتے ہیں اور end-to-end encryption کے ذریعے محفوظ نہیں ہوتے، کیونکہ server کو انہیں استعمال کرنا پڑتا ہے۔ Actual خودکار polling نہیں کرتا: syncing کے لیے آپ 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 --detach

Compose نئے image سے container دوبارہ بناتا ہے اور وہی volume دوبارہ attach کرتا ہے، اس لیے data برقرار رہتا ہے۔ clients کو بھی update کریں۔ Server اور app versions کا ایک دوسرے کے قریب رہنا متوقع ہے، اور server کے مقابلے میں بہت پرانا client version mismatch کا پیغام دے کر sync کرنے سے انکار کر سکتا ہے۔ Major version jump سے پہلے backup لیں، کیونکہ migrations پہلی start پر چلتی ہیں اور downgrade کا کوئی راستہ نہیں ہوتا۔ Actual عارضی latest tag کے ساتھ قابلِ برداشت ہے، کیونکہ اس کی state files کی ایک directory ہوتی ہے۔ اس کے برعکس، حقیقی database رکھنے والی app اس طرح قابلِ برداشت نہیں ہوتی۔ self-hosting Chatwoot میں pinned tags اور upgrade سے پہلے dump لینے کا وہ طریقہ بیان کیا گیا ہے جس کی یہاں ضرورت ہے۔

کیا خراب ہوتا ہے، اور آپ کو کیا نظر آئے گا

ایپ لوڈ ہو جاتی ہے، لیکن sync کبھی مکمل نہیں ہوتی۔ 413 کے لیے nginx access log مانیٹر کریں۔ اس کا مطلب ہے کہ client_max_body_size بہت کم مقرر ہے۔ اس کے برعکس 502 کا مطلب ہے کہ nginx چل رہا ہے، لیکن container نہیں چل رہا۔

Encryption کے options موجود نہیں، یا mobile app URL قبول نہیں کرتی۔ صفحہ secure context میں نہیں ہے۔ address bar میں IP address یا ایسا hostname دکھائی دے گا جو localhost نہیں ہے، اور اس کے ساتھ http:// بھی نظر آئے گا۔ workaround استعمال کرنے کے بجائے certificate درست کریں۔

پیغام آتا ہے کہ budget file اس version کے ساتھ compatible نہیں ہے۔ Client اور server کے versions میں فرق آ گیا ہے۔ دونوں کو ایک ہی release پر update کریں اور reload کریں۔

Container مسلسل restart ہوتا رہتا ہے۔ docker compose logs actual پڑھیں۔ /data پر permission error کا مطلب ہے کہ mounted directory container کے user کے لیے writable نہیں ہے۔ address-in-use error کا مطلب ہے کہ loopback پر کوئی دوسری چیز پہلے ہی 5006 استعمال کر رہی ہے۔

پہلی بار load ہونے میں وقت لگتا ہے۔ جب آپ budget file کھولتے ہیں تو پوری 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۔ کسی دوسری مشین سے plain HTTP کے ذریعے یہ سہولتیں دستیاب نہیں ہوتیں، اور official mobile apps plain 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 ہے۔ اس میں server-files/account.sqlite موجود ہے، جس میں logins اور sessions ہوتے ہیں، اور user-files موجود ہے، جس میں budget 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 کو password manager میں محفوظ کریں، اور اس کی ایک copy ایسی جگہ رکھیں جو اسی server پر منحصر نہ ہو۔

Actual Budget کو کتنا server درکار ہوتا ہے؟

بہت کم۔ Container static assets اور files فراہم کرتا ہے، جبکہ budget calculations browser میں ہوتی ہیں۔ 1 GB RAM کے ساتھ ایک shared vCPU اسے بغیر کسی مسئلے کے چلا لیتا ہے، اور کئی سال کی history والے گھریلو budget کی data directory عموماً دسیوں megabytes تک رہتی ہے۔ Disk pressure آپ کے backups اور دوسرے containers سے آتا ہے، Actual سے نہیں۔ اگر آپ ایسے box کی sizing کر رہے ہیں جس پر اس کے ساتھ کوئی زیادہ resources استعمال کرنے والی سروس بھی چلنی ہو، تو عموماً photo server بنیادی ضرورت طے کرتا ہے؛ اس لیے plan منتخب کرنے سے پہلے یہ دیکھیں کہ PhotoPrism اور Immich کو حقیقت میں کتنی RAM درکار ہے۔