SSD Nodes Learn 8GB RAM — $66/рік
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-01

Як встановити Actual Budget на власний VPS через Docker

Розгорніть Actual Budget на VPS за допомогою Docker Compose. Дізнайтеся, як налаштувати HTTPS для Web Crypto API, керувати томами даних, імпортувати транзакції та робити резервні копії.

Що ви створюєте

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

У цьому файлі важливі три деталі.

Образ — actualbudget/actual-server:latest, опублікований проєктом у Docker Hub та дзеркально відображений на ghcr.io/actualbudget/actual. Існує тег latest-alpine для малопотужних пристроїв.

Контейнер записує всі дані в /data. Всередині ви знайдете server-files, де зберігаються account.sqlite з вашими токенами входу та сесії, а також user-files, де знаходяться самі файли бюджету. Монтуйте цей шлях, інакше наступний docker compose pull призведе до втрати вашого бюджету. ACTUAL_DATA_DIR може змінити його розташування, але стандартне значення підходить.

Порт опубліковано лише на 127.0.0.1. Звичайний 5006:5006 публікує порт на всіх інтерфейсах, а Docker створює власні правила раніше за ufw, тому застосунок буде відкритий для інтернету навіть за умови налаштування firewall на відмову в усіх з'єднаннях. Цей нюанс пояснюється в чому опубліковані порти Docker оминають ufw. Прив'язка до loopback означає, що доступ до нього матиме лише зворотний проксі-сервер на тому самому хості.

Запустіть його:

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 означає, що контейнер не запущений, а docker compose ps покаже, що він завершив роботу. Найчастіша причина — проблеми з правами доступу до змонтованого тому, що відображається як рядок EACCES у логах.

Налаштування сертифіката та доменного імені

Спрямуйте A-запис на ваш VPS, budget.example.com, і дочекайтеся оновлення DNS. Після цього встановіть nginx та отримайте сертифікат. Посібник Certbot в Ubuntu 24.04 з nginx містить повну інформацію про випуск сертифіката та налаштування таймера його оновлення.

Блок проксі:

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 МБ, тому, коли файл перевищує цей розмір, синхронізація завершується помилкою 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 запитає, чи потрібно ввімкнути наскрізне шифрування. Погоджуйтеся, оскільки сервер зберігатиме лише зашифровані дані, що є правильним рішенням для фінансової інформації на орендованій машині. Ціна цього рішення реальна: пароль шифрування ніколи не передається на сервер, тому якщо ви його втратите, файл буде неможливо відновити, і функції скидання не існує. Запишіть його, перш ніж переходити далі.

Встановіть початкові баланси на основі поточних даних вашого банку, замість імпорту історії за багато років. Конвертне бюджетування працює з тими коштами, які у вас є зараз, тому відсутність історії ніяк не вплине на роботу.

Імпорт транзакцій

Тут чесність важливіша за ентузіазм, оскільки процес імпорту — це головна причина, чому користувачі відмовляються від self-hosted бюджетування.

Ручне введення є базовим методом, який працює завжди. Для методу конвертів це, власне, і є метою, оскільки введення даних про покупку змушує вас звернути на неї увагу.

Імпорт файлів дозволяє обробляти великі обсяги даних. Actual зчитує формати CSV, QIF, OFX та QFX, а кожен банк підтримує принаймні один із них. Виконуйте імпорт для кожного рахунку на екрані рахунку, один раз зіставте стовпці, і Actual запам'ятає цей макет для цього рахунку.

Автоматична синхронізація з банками існує, але вона потребує стороннього сервісу, оскільки сервер не може самостійно взаємодіяти з банками. Actual підтримує SimpleFIN Bridge для банків Північної Америки, Enable Banking для Європи, Akahu для Нової Зеландії та Pluggy.ai для Бразилії. GoCardless все ще підтримується, але нові облікові записи не приймає. Ви самостійно реєструєтесь у провайдера, генеруєте облікові дані та додаєте їх на сервер. Станом на липень 2026 року SimpleFIN Bridge коштує 15 доларів США на рік за підключення до 25 установ, інші сервіси мають інше ціноутворення.

Перед тим як покладатися на цей метод, прийміть два обмеження. Облікові дані API зберігаються на сервері та не захищені наскрізним шифруванням, оскільки сервер повинен використовувати їх для роботи. Крім того, Actual не виконує опитування автоматично: синхронізація — це кнопка, яку ви натискаєте вручну, а не фонове завдання.

Резервне копіювання, оскільки це лише файли

Усе, що для вас важливо, знаходиться в /opt/actual/data. Етап експорту чи створення дампу бази даних для скриптів не потрібен.

Єдина пастка — це 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 --detach

Compose створює контейнер заново на основі нового образу та повторно підключає той самий том, тому дані зберігаються. Оновіть також клієнти. Очікується, що версії сервера та застосунку будуть близькими, а клієнт, версія якого значно старіша за версію сервера, може відмовитися від синхронізації з повідомленням про невідповідність версій. Створіть резервну копію перед переходом на нову мажорну версію, оскільки міграції виконуються під час першого запуску, а шляху для відкату до попередньої версії не існує.

Що може вийти з ладу і що ви побачите

Програма завантажується, але синхронізація ніколи не завершується. Перевірте лог доступу nginx на наявність 413. Це означає, що client_max_body_size встановлено занадто низько. Помилка 502 натомість означає, що nginx працює, а контейнер — ні.

Параметри шифрування відсутні, або мобільний додаток відхиляє URL. Сторінка не знаходиться в безпечному контексті. В адресному рядку відображатиметься http:// з IP-адресою або іменем хоста, яке не є localhost. Виправте сертифікат, замість того щоб шукати обхідні шляхи.

Повідомлення про те, що файл бюджету несумісний з цією версією. Версії клієнта та сервера розсинхронізувалися. Оновіть обидві до одного релізу та перезавантажте.

Контейнер постійно перезапускається. Прочитайте docker compose logs actual. Помилка прав доступу до /data означає, що змонтований каталог недоступний для запису користувачем контейнера. Помилка "address-in-use" означає, що порт 5006 вже зайнятий іншим процесом на інтерфейсі loopback.

Перше завантаження відбувається повільно. Весь файл бюджету завантажується в браузер під час відкриття. Це один великий обсяг передачі даних, після чого відбуваються локальні зчитування. Це не проблема розміру сервера, і додавання оперативної пам'яті нічого не змінить.

FAQ

Чи потрібен Actual Budget HTTPS для роботи?

Так, на практиці. Наскрізне шифрування Actual використовує Web Crypto API браузера, а браузери надають доступ до нього лише в безпечному контексті, тобто https:// або http://localhost. При використанні звичайного HTTP з іншої машини ці функції недоступні, а офіційні мобільні додатки відхиляють URL-адреси серверів без HTTPS. Використовуйте сертифікат 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 ГБ оперативної пам'яті забезпечує стабільну роботу, а каталог даних для сімейного бюджету з історією за кілька років займає лише десятки мегабайтів. Навантаження на диск створюється вашими резервними копіями та іншими контейнерами, а не Actual.