Actual Budget в Docker Compose: готовый файл
Вести бюджет в таблице Excel надоедает через месяц, а платить $8-10 в месяц за YNAB и доверять чужому облаку баланс своей карты хочется не всем. Actual Budget — open-source приложение для бюджетирования по методу envelope (конвертов), которое можно развернуть на своём сервере за один docker-compose.yml и получить интерфейс не хуже платных аналогов, но без подписки и с данными под своим контролем. Ниже — рабочий конфиг, разбор что писать в переменные окружения и на что обратить внимание с бэкапами: тут речь о финансовых данных, ошибки дороже, чем с обычным сайтом.
Содержание
- Что такое Actual Budget и чем он отличается от Firefly III
- Готовый docker-compose.yml для быстрого старта
- Первый запуск: пароль сервера и создание бюджета
- HTTPS и reverse proxy: без этого часть функций не заработает
- Несколько бюджетов на одном сервере и общий доступ семьи
- Бэкапы и обновление версии: тут осторожность важнее скорости
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Actual Budget и чем он отличается от Firefly III
Actual реализует метод envelope budgeting: вы заранее распределяете весь доход по категориям-«конвертам» (аренда, продукты, развлечения) и тратите строго в рамках того, что в конверте осталось, а не смотрите на общий баланс карты постфактум. Это тот же подход, что в YNAB, только open-source и без обязательной подписки.
Технически Actual устроен необычно для self-hosted приложений: это не классическое клиент-сервер приложение с общей базой, а local-first система. Каждый бюджет — это SQLite-файл, который живёт локально в браузере или приложении пользователя, а сервер работает как реле синхронизации через CRDT (merkle-дерево изменений). Это даёт заметный на практике эффект: интерфейс отвечает мгновенно, потому что все операции идут в локальную копию, а не ждут round-trip к серверу, и приложение продолжает работать даже если сервер временно недоступен — изменения досинхронизируются, когда связь восстановится.
Если на этом же блоге вы уже смотрели статью про установку Firefly III, разница в философии станет понятнее:
- Firefly III — это бухгалтерская книга с двойной записью, отчётами по категориям и правилами импорта банковских выписок. Хорош, когда нужна точная картина «куда ушли деньги» постфактум, и требует отдельной MySQL/PostgreSQL базы.
- Actual Budget — про планирование вперёд: сколько денег осталось в конверте «продукты» до конца месяца. Интерфейс быстрее и приятнее для ежедневного использования, а серверная часть — один лёгкий Node.js-контейнер без внешней СУБД, потому что каждый бюджет уже сам себе SQLite-база.
Для семейного бюджета и личных финансов обычно ближе Actual, для учёта бизнеса с отчётностью и импортом выписок из десятка банков — Firefly III. Ничего не мешает поднять оба на одном сервере, они не конкурируют за ресурсы.
Готовый docker-compose.yml для быстрого старта
Официальный образ actualbudget/actual-server — это весь сервер целиком: и сам Node-процесс синхронизации, и раздача статики веб-клиента. Внешняя база не нужна.
version: "3.8"
services:
actual_server:
image: docker.io/actualbudget/actual-server:latest
container_name: actual_server
restart: unless-stopped
ports:
- "5006:5006"
volumes:
- ./actual-data:/data
environment:
ACTUAL_PORT: "5006"
# Лимиты на размер синхронизируемого файла бюджета, в МБ
ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB: "20"
ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB: "50"
ACTUAL_UPLOAD_FILE_SIZE_LIMIT_MB: "20"
Как и в любом образе с плавающим тегом, latest удобен для первого теста, но для боевой эксплуатации зафиксируйте конкретную версию — откройте страницу образа на Docker Hub, возьмите актуальный тег (у Actual используется календарное версионирование, что-то вроде 25.x.x) и пропишите его явно. Так обновление версии станет осознанным шагом, а не тем, что происходит само при пересоздании контейнера.
Запуск:
mkdir -p ~/actual-budget && cd ~/actual-budget
mkdir -p actual-data
# вставляем docker-compose.yml из примера выше
docker compose up -d
docker compose logs -f actual_server
Через 10-20 секунд сервер поднимается и слушает на http://ваш-ip:5006. Каталог ./actual-data — это всё, что нужно бэкапить: там появятся подпапки server-files (служебная база сервера, включая хэш пароля входа) и user-files (файлы каждого созданного бюджета).
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПервый запуск: пароль сервера и создание бюджета
При первом заходе на адрес сервера Actual попросит задать пароль — это не пароль конкретного бюджета, а мастер-пароль доступа к самому серверу синхронизации. Без него интерфейс работать не начнёт, так что пропустить этот шаг нельзя, и это правильно: без пароля любой, кто найдёт открытый порт 5006, получил бы доступ к вашим финансам.
После входа вы попадаете на экран выбора бюджета. Можно:
- создать новый бюджет с нуля и настроить категории под себя;
- импортировать данные из YNAB (есть готовый импортёр форматов nYNAB и старого YNAB4);
- импортировать из CSV-выгрузки банка.
При создании бюджета Actual предложит включить сквозное шифрование (end-to-end encryption) отдельным паролем для этого конкретного файла. Это важный нюанс: пароль сервера защищает вход в интерфейс, а пароль шифрования файла защищает содержимое конкретного бюджета так, что даже сам сервер хранит его как непрозрачный блоб и не может прочитать данные. Минус — если забудете этот пароль, расшифровать бюджет без него не получится никак, бэкдора и восстановления через админку нет.
Дальше desktop- и мобильные приложения Actual (Windows/macOS/Linux/iOS/Android) подключаются к тому же серверу — в настройках приложения указываете URL вашего сервера и мастер-пароль, дальше синхронизация идёт автоматически в фоне.
HTTPS и reverse proxy: без этого часть функций не заработает
Actual — прогрессивное веб-приложение (PWA) с сервис-воркером, а современные браузеры разрешают часть возможностей service worker (в том числе офлайн-режим и фоновую синхронизацию) только по HTTPS — исключение делается лишь для localhost. Если открыть сервер по обычному http://ip:5006 с телефона или ноутбука не через localhost, часть local-first магии просто не включится, а некоторые мобильные клиенты и вовсе откажутся подключаться к незащищённому адресу.
Проще всего отдать HTTPS уже работающему на сервере reverse proxy — например, Caddy с автоматическим Let's Encrypt. Держим Actual на локальном порту и добавляем блок:
ports:
- "127.0.0.1:5006:5006" # только локально, наружу не торчит
budget.example.com {
reverse_proxy 127.0.0.1:5006
}
Домен в А-записи должен указывать на IP сервера, порты 80/443 — быть свободны. Если сервер стоит за прокси, добавьте в окружение Actual переменную с адресом прокси, чтобы приложение правильно определяло реальный IP клиента для логов:
environment:
ACTUAL_TRUSTED_PROXIES: "127.0.0.1"
Если reverse proxy на сервере пока нет и заводить его ради одного приложения не хочется, у самого образа есть встроенная поддержка HTTPS напрямую через ACTUAL_HTTPS_KEY и ACTUAL_HTTPS_CERT (указываете пути к смонтированным файлам сертификата и ключа) — вариант рабочий, но обновлять сертификат в этом случае придётся руками или отдельным cron-скриптом с certbot, тогда как reverse proxy делает это сам.
Несколько бюджетов на одном сервере и общий доступ семьи
Один сервер Actual спокойно держит несколько независимых бюджетов — например, личный и семейный, или отдельные для каждого члена семьи. Каждый бюджет создаётся со своим шифрованием (или без него) и виден только тем, кто знает мастер-пароль сервера и, если включено, пароль шифрования конкретного файла.
Важное ограничение, которое стоит понимать заранее: по умолчанию (ACTUAL_LOGIN_METHOD: password) у сервера один общий мастер-пароль на всех, а не отдельные учётки с ролями, как в банковском приложении. Для семьи из двух-трёх человек, которым можно доверять друг другу пароль, это не проблема. Если нужно разграничение — кто-то видит только свой бюджет, а не все — начиная с версий, где появилась поддержка ACTUAL_LOGIN_METHOD: header, можно вынести аутентификацию на внешний SSO-прокси (например, Authelia) и разруливать доступ уже на его уровне, но это заметно усложняет схему ради функции, которую сам Actual изначально не проектировал как многопользовательскую с ролями.
Практичнее для большинства семей: один мастер-пароль знают все, кому доверяете доступ к серверу, а приватность внутри бюджета (если она вообще нужна) достигается просто отдельными бюджетными файлами с разными паролями шифрования на каждый.
Бэкапы и обновление версии: тут осторожность важнее скорости
Это финансовые данные, поэтому бэкап-стратегия должна быть надёжнее, чем «раз в неделю как получится». Бэкапить нужно весь каталог /data — в нём и служебная база сервера, и SQLite-файлы всех бюджетов:
tar -czf actual-backup-$(date +%F).tar.gz -C ~/actual-budget actual-data
Для регулярных бэкапов с дедупликацией и шифрованием удобнее не городить cron с tar вручную, а поднять рядом BorgBackup в отдельном контейнере — он умеет ежедневные снапшоты с ротацией и не раздувает диск, в отличие от полных архивов каждый день.
Про обновление версии — здесь стоит явная рекомендация: не ставьте Actual Budget на автообновление через watchtower или аналоги. При обновлении сервер применяет миграции к SQLite-файлам бюджетов, и если миграция упадёт на середине (баг в новой версии, нехватка места на диске, обрыв), файл может остаться в промежуточном состоянии. С финансовыми данными это не тот риск, который стоит автоматизировать вслепую. Правильный порядок:
# 1. Бэкап перед обновлением — всегда
tar -czf actual-backup-pre-update-$(date +%F).tar.gz -C ~/actual-budget actual-data
# 2. Смотрим changelog новой версии на GitHub actualbudget/actual —
# были ли breaking changes или ручные шаги миграции
# 3. Обновляем
docker compose pull actual_server
docker compose up -d actual_server
docker compose logs -f actual_server
Если после обновления в логах ошибки миграции или интерфейс не открывается — останавливаем контейнер, разворачиваем бэкап каталога /data поверх текущего и разбираемся уже без спешки, с рабочей копией под рукой.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Нужна ли для Actual Budget отдельная база данных вроде PostgreSQL?
Нет, это ключевое отличие от того же Firefly III. Каждый бюджет — самостоятельный SQLite-файл, сервер только синхронизирует изменения между вашими устройствами. Внешняя СУБД не нужна, и это упрощает и бэкап, и восстановление — весь объект бэкапа это папка /data.
Что будет с данными, если сервер недоступен несколько дней?
Ничего критичного — приложение на устройстве работает с локальной копией бюджета полностью автономно, вы продолжаете вносить операции. Как только сервер снова станет доступен, изменения досинхронизируются автоматически через merkle-дерево без ручного разрешения конфликтов в большинстве случаев.
Хватит ли самого дешёвого VPS?
С запасом. Actual — лёгкий Node.js-процесс без тяжёлой СУБД, для одного-двух бюджетов и нескольких пользователей достаточно 512 МБ - 1 ГБ RAM и минимального CPU. Требования растут только с числом одновременных клиентов, синхронизирующихся часто, а не с размером самого бюджета.
Можно ли забыть пароль сквозного шифрования и восстановить бюджет?
Нет, и это осознанный компромисс безопасности — сервер хранит зашифрованный файл, не может расшифровать его сам и, соответственно, не может помочь его восстановить. Держите пароли шифрования в менеджере паролей отдельно от мастер-пароля сервера.
Как перенести Actual с одного сервера на другой?
Останавливаете контейнер, копируете весь каталог /data (сам том с server-files и user-files) на новый сервер, поднимаете тот же docker-compose.yml с тем же образом и версией, указываете новый volume — сервер подхватит существующие бюджеты и пароль входа как есть, без экспорта-импорта.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →