Firefly III в Docker Compose: готовый файл
Приложения для учёта финансов вроде YNAB или Monarch удобны, но каждый месяц отправляют ваши транзакции на чужие серверы — и просят за это подписку в долларах, которую из России ещё поди оплати. Firefly III решает обе проблемы: это open-source менеджер личных финансов с бюджетами, счетами, отчётами и правилами автоматической категоризации, который вы разворачиваете сами, на своём сервере, и данные о том, сколько вы потратили на кофе, не покидают вашу инфраструктуру. Ниже — рабочий docker-compose.yml, который поднимает Firefly III вместе с PostgreSQL за один docker compose up, плюс нюансы, которые обычно вылезают уже после установки.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Firefly III и кому он подходит
Firefly III — это веб-приложение на PHP (Laravel), которое закрывает типичный набор задач личных финансов: несколько счетов (наличные, карты, вклады), бюджеты по категориям, повторяющиеся транзакции, теги, правила автоматической разметки платежей и подробные отчёты — от помесячного баланса до net worth за год. Есть импорт из CSV и отдельный модуль Data Importer, который умеет разбирать банковские выписки и синхронизироваться через открытый стандарт GoCardless (бывший Nordigen) для части европейских банков — для российских банков автоматической интеграции нет, операции заводятся вручную или через CSV.
Кому это подходит:
- тем, кто ведёт семейный или личный бюджет и хочет видеть реальную картину трат, а не гадать по выпискам;
- фрилансерам и небольшим ИП, которым нужно разделять личные и рабочие потоки денег без бухгалтерского SaaS;
- людям, которым принципиально важно, чтобы данные о доходах и расходах не лежали на серверах третьей компании.
Для учёта бизнес-финансов с двойной записью и налоговой отчётностью Firefly III не подойдёт — это про личные и семейные деньги, не про ERP.
Требования к серверу
Firefly III — не тяжёлое приложение, но PHP-FPM плюс PostgreSQL плюс опциональный Data Importer суммарно просят чуть больше, чем «самый дешёвый тариф»:
| Ресурс | Минимум | Комфортно |
|---|---|---|
| CPU | 1 vCPU | 2 vCPU |
| RAM | 1 GB | 2 GB |
| Диск | 10 GB SSD | 20+ GB SSD |
| ОС | Ubuntu 24.04 / Debian 12 | Ubuntu 24.04 |
С 1 GB RAM всё запустится и будет работать для одного-двух пользователей, но если планируете держать на том же сервере что-то ещё, закладывайте 2 GB — PostgreSQL съедает оперативку под кэш страниц, и на 1 GB при импорте CSV на пару тысяч строк процесс может упереться в OOM killer.
Для установки Docker с нуля на чистой системе подойдёт инструкция Ubuntu 24.04: установка Docker с нуля — она же годится и для Debian с минимальными правками.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверГотовый docker-compose.yml
Ниже — минимальная, но production-пригодная конфигурация: сам Firefly III, отдельный контейнер PostgreSQL, том для загруженных файлов (аттачей и импортов) и cron-контейнер для фоновых задач (напоминания о повторяющихся транзакциях, автоматические правила).
Создайте директорию проекта и файл .env:
mkdir -p ~/firefly-iii && cd ~/firefly-iii
touch .env
Сгенерируйте два случайных значения — APP_KEY (32 байта в base64 с префиксом base64:) и пароль для БД:
echo "APP_KEY=base64:$(openssl rand -base64 32)"
echo "DB_PASS=$(openssl rand -base64 24)"
echo "STATIC_CRON_TOKEN=$(openssl rand -hex 16)"
Впишите результаты в .env:
# .env
APP_ENV=production
APP_KEY=base64:вставьте_сгенерированный_ключ
APP_URL=https://finance.example.com
TZ=Europe/Moscow
DB_HOST=firefly-db
DB_PORT=5432
DB_CONNECTION=pgsql
DB_DATABASE=firefly
DB_USERNAME=firefly
DB_PASSWORD=вставьте_пароль_бд
STATIC_CRON_TOKEN=вставьте_сгенерированный_токен
TRUSTED_PROXIES=**
Теперь сам docker-compose.yml:
services:
firefly-app:
image: fireflyiii/core:latest
container_name: firefly-app
restart: unless-stopped
env_file: .env
volumes:
- firefly_upload:/var/www/html/storage/upload
depends_on:
firefly-db:
condition: service_healthy
ports:
- "127.0.0.1:8080:8080"
networks:
- firefly-net
firefly-db:
image: postgres:16-alpine
container_name: firefly-db
restart: unless-stopped
environment:
POSTGRES_DB: firefly
POSTGRES_USER: firefly
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- firefly_db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U firefly -d firefly"]
interval: 10s
timeout: 5s
retries: 5
networks:
- firefly-net
firefly-cron:
image: alpine:3.20
container_name: firefly-cron
restart: unless-stopped
depends_on:
- firefly-app
entrypoint: >
sh -c "apk add --no-cache curl tzdata >/dev/null &&
echo '*/15 * * * * curl -s -m 30 http://firefly-app:8080/api/v1/cron/${STATIC_CRON_TOKEN}' | crontab - &&
crond -f -L /dev/stdout"
networks:
- firefly-net
volumes:
firefly_db:
firefly_upload:
networks:
firefly-net:
Обратите внимание: в примере с openssl rand переменная для наглядности названа DB_PASS, а в реальном .env для приложения используйте именно DB_PASSWORD — это имя ждёт и Firefly III, и docker-compose.yml.
Порт приложения намеренно опубликован только на 127.0.0.1:8080 — снаружи Firefly III должен быть доступен исключительно через обратный прокси с HTTPS, никакого прямого HTTP-доступа в открытую сеть быть не должно.
Запуск:
docker compose up -d
docker compose logs -f firefly-app
Первый старт займёт минуту-две — контейнер прогоняет миграции БД. Когда в логах появится строка about listening, идите по http://127.0.0.1:8080 (через SSH-туннель, если ещё нет прокси) и создайте первого пользователя-администратора.
Обратный прокси и HTTPS
Публиковать финансовое приложение без TLS нельзя, поэтому сразу вешаем обратный прокси. Если у вас уже есть Caddy на сервере — конфиг простой:
finance.example.com {
reverse_proxy 127.0.0.1:8080
}
Caddy сам получит и обновит сертификат Let's Encrypt. Подробности первичной настройки — в статье Caddy с авто-SSL на Ubuntu 24.04: пошаговая установка, а если что-то пошло не так — там же есть разбор частых ошибок Caddy с авто-SSL.
Если предпочитаете nginx:
server {
listen 443 ssl http2;
server_name finance.example.com;
ssl_certificate /etc/letsencrypt/live/finance.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/finance.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
Не забудьте после этого выставить APP_URL в .env строго на https:// адрес и перезапустить контейнер (docker compose up -d) — иначе Firefly III будет генерировать неправильные ссылки внутри интерфейса и в письмах.
Data Importer: подключение банковских выписок
Ручной ввод каждой транзакции быстро надоедает, поэтому у Firefly III есть отдельный компонент — Data Importer, который умеет читать CSV/CAMT.053-выгрузки и (для части банков ЕС) синхронизироваться по открытому банковскому API через GoCardless. Для банков РФ прямой интеграции нет — работаем через CSV.
Добавьте в тот же docker-compose.yml (или в отдельный файл docker-compose.importer.yml):
services:
firefly-importer:
image: fireflyiii/data-importer:latest
container_name: firefly-importer
restart: unless-stopped
environment:
FIREFLY_III_URL: "http://firefly-app:8080"
FIREFLY_III_ACCESS_TOKEN: "вставьте_личный_токен_из_UI"
VANITY_URL: "https://import.example.com"
ports:
- "127.0.0.1:8081:8080"
networks:
- firefly-net
networks:
firefly-net:
external: true
Личный токен создаётся в UI: Profile → OAuth → Personal Access Tokens. Экспортируйте выписку из банка в CSV, зайдите в Data Importer, укажите соответствие колонок (дата, сумма, описание, счёт) — мастер запомнит конфигурацию в виде JSON-профиля, который можно переиспользовать при регулярном импорте.
Бэкапы: что действительно нужно сохранять
Все финансовые данные Firefly III живут в PostgreSQL — том firefly_upload содержит только приложенные файлы (сканы чеков и т.п.), а не транзакции. Значит, приоритет бэкапа — дамп базы:
#!/bin/bash
# /opt/scripts/backup-firefly.sh
BACKUP_DIR="/opt/backups/firefly"
DATE=$(date +%Y%m%d-%H%M%S)
mkdir -p "$BACKUP_DIR"
docker exec firefly-db pg_dump -U firefly firefly | gzip > "$BACKUP_DIR/firefly-db-$DATE.sql.gz"
# том с аттачами
docker run --rm -v firefly-iii_firefly_upload:/data -v "$BACKUP_DIR":/backup alpine \
tar czf "/backup/firefly-upload-$DATE.tar.gz" -C /data .
# храним последние 14 копий
find "$BACKUP_DIR" -name "firefly-*.gz" -mtime +14 -delete
Добавьте в crontab (crontab -e) ежедневный запуск в тихое время:
0 3 * * * /opt/scripts/backup-firefly.sh >> /var/log/firefly-backup.log 2>&1
Про настройку планировщика подробнее — в статье как установить и настроить cron-задачи на VPS. Если хотите более серьёзную схему с версионированием и дедупликацией (а для финансовых данных это разумно), посмотрите на BorgBackup — есть отдельный разбор BorgBackup в Docker Compose, который можно направить на тот же каталог с дампами. Восстановление дампа — обратная операция:
gunzip -c firefly-db-20260815-030000.sql.gz | docker exec -i firefly-db psql -U firefly -d firefly
Держите хотя бы одну копию бэкапа вне самого сервера — на объектном хранилище или другом VPS. Копия рядом с оригиналом не спасает при потере диска.
Обновление и типичные проблемы
Обновление образа — стандартный докеровский цикл:
docker compose pull
docker compose up -d
docker compose logs -f firefly-app
Firefly III сам прогонит миграции БД при старте новой версии. Перед крупным мажорным обновлением (например, между релизами с разницей в номере минорной версии на 3+) стоит сделать свежий дамп — Laravel-миграции штука надёжная, но откатить их назад без бэкапа не получится.
Частые проблемы, с которыми сталкиваются при первом запуске:
- 500 Server Error сразу после старта. Почти всегда — неверный или отсутствующий
APP_KEY, либо приложение стартовало раньше, чем БД прошла healthcheck. Проверьтеdocker compose logs firefly-appи убедитесь, что вdocker-compose.ymlестьdepends_on: condition: service_healthy. - Ошибки подключения к БД (
SQLSTATE[08006]). Обычно рассинхронизация имени сервиса:DB_HOSTв.envдолжен точно совпадать с именем сервиса БД вdocker-compose.yml(в примере —firefly-db), а не сlocalhost. - Cron-задачи не выполняются (повторяющиеся транзакции не создаются, правила не срабатывают). Проверьте, что
STATIC_CRON_TOKENв.envи в команде curl контейнераfirefly-cronсовпадают, и что запрос реально доходит —docker compose logs firefly-cron. - После обновления интерфейс генерирует ссылки на http вместо https. Проверьте
APP_URLв.envи заголовкиX-Forwarded-Protoв конфиге прокси — без них Laravel не понимает, что запрос пришёл по HTTPS.
Если проблема шире конкретно Firefly III и контейнер вообще не поднимается — общий чек-лист есть в статье Docker-контейнер не запускается.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли перенести данные из другого финансового трекера?
Да, через CSV — экспортируйте историю операций из старого приложения (большинство, включая банковские выписки, поддерживают CSV) и заведите импорт через Data Importer, сопоставив колонки вручную один раз.
Работает ли автоматическая синхронизация с российскими банками?
Нет, прямых банковских интеграций для РФ у Firefly III и его Data Importer не предусмотрено — только ручной ввод или CSV-импорт выписок.
Нужен ли отдельный сервер только под Firefly III?
Нет, при 2 GB RAM он спокойно уживается с другими лёгкими сервисами на одном VPS — важно лишь не публиковать порт приложения напрямую наружу и держать всё за одним обратным прокси.
Что будет, если забыть мастер-пароль администратора?
Пароль можно сбросить напрямую через artisan-команду внутри контейнера: docker exec -it firefly-app php artisan firefly-iii:set-user-password, следуя интерактивным подсказкам.
Можно ли вести несколько пользователей (семью) в одном инстансе?
Firefly III однопользовательский по своей модели данных — каждый член семьи должен либо иметь отдельного пользователя с отдельным набором счетов на одном сервере, либо использовать общие учётные данные для входа, если разделение не критично.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →