איך להתקין Actual Budget ב-VPS פרטי עם Docker Compose
מדריך להתקנת Actual Budget ב-VPS עם Docker Compose: נפח הנתונים, מדוע הדפדפן דורש HTTPS, יצירת קובץ תקציב, ייבוא בנק וגיבויים.
מה אתם בונים
Actual Budget היא אפליקציה לניהול תקציב בשיטת המעטפות, באירוח עצמי. זהו בדרך כלל הפתרון למי שמחפש חלופה ל-YNAB שאפשר לארח בעצמו. השרת פועל בתוך קונטיינר אחד, משתמש באמצעי אחסון נתונים אחד ובשם HTTPS אחד. כל הדרוש לתקציב רגיל פועל ללא קושי ב-VPS הקטן ביותר שאפשר לשכור, משום שהשרת מאחסן בעיקר קבצים ומסנכרן אותם.
חשוב להבין את הארכיטקטורה לפני שמקלידים פקודה כלשהי. התקציב עצמו הוא מסד נתונים של SQLite שנמצא בדפדפן ובכל אפליקציה לנייד. השרת שאתם עומדים להתקין הוא נקודת קצה לסנכרון: הוא מחזיק את רשימת החשבונות, את קובצי התקציב ואת יומן השינויים, שמאפשרים לטלפון ולמחשב הנייד להציג את אותו מצב. לכן האפליקציה ממשיכה לפעול כשהשרת אינו זמין, ולכן אובדן השרת אינו גורם לאובדן התקציב, כל עוד עותק אחד שלו עדיין נמצא אצל לקוח כלשהו.
מדוע השרת זקוק ל-HTTPS
Actual דורש HTTPS, ואין מדובר בדרישה פורמלית. דפדפנים חושפים את Web Crypto API, הממשק שבו Actual משתמש להצפנה מקצה לקצה, רק בהקשר שהמפרט מכנה הקשר מאובטח. הקשר מאובטח הוא https:// או http://localhost. אם טוענים את היישום מ-http://203.0.113.10:5006 בדפדפן במחשב אחר, התכונות האלה פשוט אינן זמינות, מכיוון שהדפדפן מעולם לא מסר אותן לדף. גם גרסאות המובייל הרשמיות מסרבות לכתובת URL של שרת http:// רגיל.
לכן קיימות שתי תצורות אפשריות. מציבים אישור אמיתי בשם אמיתי לפני הקונטיינר, כפי שעושה מדריך זה. לחלופין, נותנים לשרת אישור בחתימה עצמית באמצעות ACTUAL_HTTPS_KEY ו-ACTUAL_HTTPS_CERT, כפי שמתועד בפרויקט, ומקבלים אזהרת דפדפן בכל מכשיר. אישור חינמי מ-Let's Encrypt מתקבל בתוך חמש דקות, לכן בחרו באפשרות הראשונה.
התקנת Actual Budget באמצעות Docker Compose
התקן תחילה את Docker אם זו מערכת חדשה. אם תחביר קובץ Compose חדש לך, המדריך יסודות Docker Compose עבור VPS מסביר את השדות שבהם נעשה שימוש להלן.
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, שהפרויקט פרסם ב-Docker Hub ושמראה בכתובת ghcr.io/actualbudget/actual. קיים תג latest-alpine עבור מכונות בעלות צריכת חשמל נמוכה.
ה-container כותב הכול תחת /data. בתוכו נמצאים server-files, שמכיל את account.sqlite עם פרטי הכניסה ואסימוני ההפעלה שלך, וכן user-files, שמכיל את קובצי התקציב עצמם. יש למפות את הנתיב הזה, אחרת docker compose pull הבא ימחק את התקציב שלך. ACTUAL_DATA_DIR יכול להעביר אותו, אך ברירת המחדל מתאימה.
הפורט מפורסם רק ב-127.0.0.1. 5006:5006 ללא כתובת מפרסם את הפורט בכל הממשקים, ו-Docker כותב כללים משלו לפני ufw. לכן היישום יהיה חשוף לאינטרנט גם כאשר חומת האש מוגדרת לדחות הכול. הסיבה לכך מוסברת במדריך מדוע פורטים ש-Docker מפרסם עוקפים את ufw. קישור ל-loopback מאפשר רק ל-reverse proxy באותה מכונה להגיע אליו.
הפעל אותו:
cd /opt/actual
docker compose up --detach
docker compose logs -f actualהיומן מתייצב לאחר שהשרת מדווח שהוא מאזין בפורט 5006. בדוק אותו מקומית לפני שתיגע ב-DNS:
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5006/תוצאה של 200 פירושה שהיישום משרת בקשות. תוצאה של curl: (7) Failed to connect פירושה שה-container אינו פועל, ו-docker compose ps יציג שהוא הופסק. הסיבה הרגילה היא בעיית הרשאות ב-volume הממופה, שמופיעה כשורת EACCES ביומן.
הצב תעודה ושם אמיתי בחזית
הפנה רשומת A אל ה-VPS, budget.example.com, והמתן עד שהרשומה תיפתר. לאחר מכן התקן את nginx והנפק את התעודה. המדריך Certbot ב-Ubuntu 24.04 עם nginx מסביר בפירוט את הנפקת התעודה ואת טיימר החידוש.
בלוק ה-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 היא השורה שאנשים שוכחים. קובץ התקציב מועלה במלואו בעת סנכרון מלא. ברירת המחדל של Nginx היא גוף בקשה בגודל 1 MB, ולכן לאחר שהקובץ גדל מעבר לגודל זה, הסנכרון נכשל עם 413 Request Entity Too Large ביומן הגישה של nginx, בעוד שהיישום מציג רק שגיאת סנכרון כללית. לשרת יש מגבלות נפרדות משלו: ברירת המחדל של ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB היא 20, וברירת המחדל של ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB היא 50. לכן הגדירו את מגבלת nginx לערך גבוה יותר מהמגבלה הרלוונטית עבורכם.
טענו מחדש ובדקו:
sudo nginx -t && sudo systemctl reload nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://budget.example.com/ההפעלה הראשונה: הסיסמה וקובץ התקציב הראשון שלך
פתח את https://budget.example.com בדפדפן. במסך הראשון תתבקש להגדיר סיסמה לשרת. הסיסמה היחידה הזו מגינה על השרת כולו, לכן צור סיסמה אקראית וארוכה ושמור אותה במקום שתוכל למצוא שוב, למשל במנהל סיסמאות Vaultwarden באירוח עצמי. אין צורך ליצור חשבונות משתמשים. השרת של Actual מתוכנן מלכתחילה לפעול עם סיסמה יחידה, לכן שיתוף תקציב פירושו שיתוף הסיסמה הזו.
לאחר מכן צור קובץ תקציב. Actual ישאל אם להפעיל הצפנה מקצה לקצה. השב בחיוב, והשרת ישמור צופן בלבד. זו הבחירה הנכונה עבור נתונים פיננסיים במכונה שכורה. יש לכך מחיר ממשי: סיסמת ההצפנה לעולם אינה מגיעה לשרת, לכן אם תאבד אותה הקובץ יאבד, ואין אפשרות לאיפוס. כתוב אותה לפני שתמשיך מעבר למסך הזה.
הגדר את היתרות ההתחלתיות לפי הנתונים העדכניים של הבנק שלך, במקום לייבא היסטוריה של שנים. תקצוב במעטפות מתקדם מהכסף שיש לך עכשיו, ולכן היסטוריה ריקה אינה עולה לך דבר.
קבלת עסקאות
כאן חשוב להיות ענייניים ולא נלהבים מדי, משום שתהליך הייבוא הוא הסיבה העיקרית לכך שמשתמשים מוותרים על ניהול תקציב באירוח עצמי.
הזנה ידנית היא נקודת הבסיס, והיא תמיד עובדת. בשיטת מעטפות, אפשר לטעון שזהו העיקר, משום שהקלדת רכישה גורמת לכם לשים לב אליה.
ייבוא מקובץ מטפל ברוב הנתונים. Actual קורא קובצי CSV, QIF, OFX ו־QFX, וכל בנק מייצא לפחות אחד מהפורמטים האלה. בצעו ייבוא לכל חשבון ממסך החשבון, מפו את העמודות פעם אחת, ו־Actual יזכור את המבנה הזה עבור החשבון.
קיימת גם סנכרון אוטומטי עם הבנק, אך הוא דורש שירות של צד שלישי, משום שהשרת אינו יכול לתקשר עם הבנקים בעצמו. Actual תומך ב־SimpleFIN Bridge עבור בנקים בצפון אמריקה, ב־Enable Banking עבור אירופה, ב־Akahu עבור ניו זילנד וב־Pluggy.ai עבור ברזיל. GoCardless עדיין נתמך, אך אינו מקבל חשבונות חדשים. עליכם להירשם אצל הספק בעצמכם, ליצור פרטי התחברות ולהוסיף אותם לשרת. נכון ל־July 2026, SimpleFIN Bridge גובה 15 דולרים אמריקאיים לשנה עבור עד 25 מוסדות, ולשירותים האחרים יש תמחור שונה.
יש שתי מגבלות שכדאי להביא בחשבון לפני שמסתמכים על אפשרות זו. פרטי ה־API נמצאים בשרת ואינם מוגנים בהצפנה מקצה לקצה, משום שהשרת צריך להשתמש בהם. בנוסף, Actual אינו מבצע תשאול מחזורי: הסנכרון מופעל באמצעות כפתור, ולא כמשימת רקע.
גיבויים, כי מדובר רק בקבצים
כל מה שחשוב לכם נמצא תחת /opt/actual/data. אין שלב ייצוא ואין צורך ליצור סקריפט ליצירת dump של מסד נתונים.
המלכודת היחידה היא SQLite. העתקת account.sqlite בזמן שהשרת כותב אליו עלולה ללכוד עסקה שלא הושלמה, ולא תגלו זאת עד שתנסו לשחזר. עצרו את הקונטיינר למשך השניות הספורות הנדרשות להעתקה:
cd /opt/actual
docker compose stop
restic -r sftp:backup@backup.example.com:/srv/restic backup /opt/actual/data
docker compose startהוסיפו זאת ללוח זמנים באמצעות הגישה המתוארת ב-גיבויי restic ב-VPS, הכוללת הגדרת מאגר, מדיניות שמירת גיבויים ותרגול שחזור. בצעו את תרגול השחזור. גיבוי שמעולם לא שוחזר הוא רק ניחוש.
הגיבויים ש-Actual יוצר בצד הלקוח הם עניין נפרד שכדאי להכיר. הדפדפן שומר עותקים עדכניים של קובץ התקציב, וניתן לגשת אליהם מתפריט הקובץ. כך אפשר לטפל במקרה של "מחקתי קטגוריה בטעות" בלי לגעת בשרת כלל.
עדכון השרת
cd /opt/actual
docker compose pull
docker compose up --detachCompose יוצר מחדש את המכולה מה-image החדש ומחבר אליה מחדש את אותו volume, ולכן הנתונים נשמרים. עדכנו גם את הלקוחות. גרסאות השרת והיישום צריכות להישאר קרובות זו לזו, ולקוח שגרסתו ישנה בהרבה מגרסת השרת עלול לסרב לבצע סנכרון ולהציג הודעה על אי-התאמת גרסאות. צרו גיבוי לפני מעבר לגרסה ראשית חדשה, משום שהעברות נתונים מתבצעות בהפעלה הראשונה ואין אפשרות לחזור לגרסה קודמת.
מה מתקלקל ומה תראו
האפליקציה נטענת, אך הסנכרון אינו מסתיים. בדקו את יומן הגישה של nginx וחפשו את 413. המשמעות היא שהערך של client_max_body_size נמוך מדי. 502 מציין במקום זאת ש-nginx פעיל, אך הקונטיינר אינו פעיל.
אפשרויות ההצפנה חסרות, או שהאפליקציה לנייד דוחה את כתובת ה-URL. הדף אינו נמצא בהקשר מאובטח. בשורת הכתובת יופיע http:// עם כתובת IP או עם שם מארח שאינו localhost. תקנו את האישור במקום לעקוף את הבעיה.
מופיעה הודעה שקובץ התקציב אינו תואם לגרסה זו. גרסאות הלקוח והשרת אינן מסונכרנות. עדכנו את שתיהן לאותה מהדורה וטענו מחדש.
הקונטיינר מופעל מחדש בלולאה. קראו את docker compose logs actual. שגיאת הרשאה עבור /data פירושה שהספרייה שנטענה אינה ניתנת לכתיבה על ידי המשתמש של הקונטיינר. שגיאה המציינת שהכתובת כבר בשימוש פירושה שתהליך אחר כבר משתמש ביציאה 5006 בממשק loopback.
הטעינה הראשונה איטית. כל קובץ התקציב יורד לדפדפן כשפותחים אותו. מדובר בהעברה גדולה אחת ולאחריה בקריאות מקומיות. זו אינה בעיה של גודל השרת, והוספת זיכרון RAM לא תשנה זאת.
FAQ
האם Actual Budget זקוק ל-HTTPS כדי לפעול?
כן, בפועל. ההצפנה מקצה לקצה של Actual משתמשת ב-API של Web Crypto בדפדפן, ודפדפנים חושפים אותו רק בהקשר מאובטח, כלומר https:// או http://localhost. בחיבור HTTP רגיל ממחשב אחר, התכונות האלה אינן זמינות, והיישומים הרשמיים למכשירים ניידים דוחים כתובת URL של שרת HTTP רגיל. השתמשו באישור של Let's Encrypt עבור שם מארח אמיתי, או באישור בחתימה עצמית עם ACTUAL_HTTPS_KEY ו-ACTUAL_HTTPS_CERT אם אתם משתמשים תמיד בדפדפן במחשב שולחני.
האם Actual יכול לייבא את תנועות הבנק שלי באופן אוטומטי?
רק באמצעות שירות צד שלישי שנרשמים אליו באופן עצמאי: SimpleFIN Bridge בצפון אמריקה, Enable Banking באירופה, Akahu בניו זילנד או Pluggy.ai בברזיל. GoCardless נתמך, אך אינו מקבל חשבונות חדשים. פרטי הגישה ל-API נשמרים בשרת שלכם ואינם מוגנים בהצפנה מקצה לקצה. גם הסנכרון ידני, לכן עליכם ללחוץ על לחצן, ואין תהליך שרץ ברקע ובודק עדכונים. ייבוא של CSV, QIF, OFX ו-QFX אינו דורש שירות צד שלישי כלל.
על מה בדיוק עליי ליצור גיבוי?
על ספריית הנתונים שמחוברת כ-מתקינה, והיא /opt/actual/data במדריך זה. היא מכילה את server-files/account.sqlite, עם פרטי הכניסה וההפעלות, ואת user-files, עם קובצי התקציב. עצרו את הקונטיינר לפני ההעתקה, מכיוון שהעתקה של מסד נתונים חי מסוג SQLite עלולה ללכוד כתיבה חלקית. שום רכיב אחר בשרת אינו מכיל מצב.
מה קורה אם אני מאבד את סיסמת ההצפנה?
אי אפשר לשחזר את הקובץ. הסיסמה אינה מגיעה לעולם לשרת, וזו כל מטרתה של ההצפנה מקצה לקצה, לכן אין אפשרות לאיפוס ואין ערוץ תמיכה לשחזור. שמרו אותה במנהל סיסמאות מיד לאחר יצירת הקובץ, ושמרו עותק במקום שאינו תלוי באותו שרת.
כמה משאבי שרת דרושים ל-Actual Budget?
מעט מאוד. הקונטיינר מגיש נכסים וקבצים סטטיים, וחישובי התקציב מתבצעים בדפדפן. ליבת vCPU משותפת אחת עם 1 GB של RAM מספיקה להפעלתו ללא בעיות, וספריית הנתונים של תקציב ביתי עם היסטוריה של כמה שנים נשארת בגודל של עשרות מגה-בייטים. עומס האחסון נובע מהגיבויים שלכם ומהקונטיינרים האחרים, ולא מ-Actual.