1. Зачем сисадмину и вебмастеру независимый трекер регулярных расходов
Современное управление инфраструктурой неизбежно приводит к фрагментации платежей. Системный администратор, DevOps-инженер или вебмастер часто держит под управлением десятки сервисов у разных поставщиков: виртуальные серверы у нескольких облачных провайдеров, доменные имена у различных аккредитованных регистраторов, коммерческие SSL-сертификаты, корпоративные почтовые шлюзы, S3-хранилища и платные API искусственного интеллекта (OpenAI, Claude).
В такой распределенной среде регулярно возникают типовые критические инциденты:
- Внезапный простой боевого сервера (Downtime): хостинг-провайдер списывает оплату за VDS, баланс карты оказывается нулевым, и сервер мгновенно блокируется биллингом, парализуя работу сайтов и API.
- Потеря доменного имени: забытый дедлайн продления домена приводит к его снятию с делегирования, а через период Grace Period адрес перехватывают сквоттеры, создавая риск потери домена и существенных финансовых затрат на его выкуп.
- Непрозрачные списания в разных валютах: часть инфраструктуры оплачивается в рублях, зарубежные шлюзы — в долларах и евро, а регулярные списания размываются по банковским выпискам, не давая увидеть реальную стоимость владения проектом (TCO).
- Утечка данных в проприетарные SaaS-трекеры: использование сторонних облачных сервисов учета финансов подвергает риску конфиденциальность (список ваших провайдеров, IP-адресов, доменов и корпоративных инструментов попадает в чужие базы данных).
Wallos — это современный open-source инструмент с открытым исходным кодом, созданный специально для автономного (self-hosted) учета регулярных подписок, платежей за инфраструктуру и домены. Он собирает все статьи расходов в наглядный единый интерфейс, автоматически пересчитывает валюты по курсу Европейского центрального банка (ЕЦБ) и заблаговременно предупреждает администратора через Telegram-бота о приближающихся платежах.
2. Архитектура и системные требования: легковесность PHP 8.3 и SQLite
В отличие от тяжелых систем класса ERP или корпоративных менеджеров подписок, требующих для работы стек Java, Node.js или связку из нескольких контейнеров с PostgreSQL и Redis, Wallos спроектирован по канонам минималистичной эффективности. Весь сервис поставляется в виде единого монолитного контейнера bellamy/wallos на базе дистрибутива Alpine Linux.
| Компонент стека | Технология / Версия | Назначение в архитектуре Wallos |
|---|---|---|
| Базовый образ | php:8.3-fpm-alpine |
Легковесная среда выполнения PHP 8.3 с оптимизированным потреблением памяти до 25–30 МБ. |
| Внутренний веб-сервер | nginx (Alpine) |
Обработка статических ассетов (CSS, SVG, логотипы) и проксирование запросов к FastCGI. |
| База данных | SQLite 3 (файл wallos.db) |
Полное отсутствие накладных расходов на TCP-сокеты СУБД; атомарные транзакции и предельно простой бэкап в один файл. |
| Фоновый планировщик | Пакет dcron (демон crond) |
Встроенный в образ Alpine планировщик cron, запускающий скрипты обновления курсов валют и отправки уведомлений. |
Для развертывания Wallos подойдет абсолютно любой доступный сервер: минимально достаточно 1 vCPU и 512 МБ RAM. На тестовом стенде Ubuntu 24.04 LTS при одном администраторе и 15 настроенных подписках утилита docker stats --no-stream фиксирует фактическое потребление всего 22–26 МБ оперативной памяти, что позволяет без труда подселить контейнер на уже работающий сервер рядом с другими сервисами или мониторингом в Beszel.
3. Подготовка каталогов и манифест Docker Compose с лимитами ресурсов
Развертывание сервиса организуем в стандартном каталоге /opt/wallos. Для сохранения состояния контейнера при обновлениях выделим два постоянных тома (volumes): директорию для базы данных SQLite и каталог для хранения пользовательских логотипов сервисов.
Подключитесь к вашему VDS по SSH и выполните подготовительные команды:
sudo mkdir -p /opt/wallos/db /opt/wallos/logos
cd /opt/wallos
В официальном скрипте инициализации контейнера (startup.sh) по умолчанию заложены переменные PUID=82 и PGID=82 (пользователь и группа www-data в Alpine). Зададим соответствующие права владения на хосте, чтобы процесс внутри контейнера имел беспрепятственный доступ на запись:
sudo chown -R 82:82 /opt/wallos/db /opt/wallos/logos
sudo chmod -R 775 /opt/wallos/db /opt/wallos/logos
Совет: если в вашей системе контейнеры запускаются под нестандартным локальным пользователем, вы можете явно переопределить переменные PUID и PGID в секции environment манифеста Compose под ваш хостовый UID/GID.
Создайте манифест docker-compose.yml с помощью текстового редактора nano docker-compose.yml:
services:
wallos:
# Фиксация стабильного релиза (v5.8.3) для защиты от поломок схемы БД при автообновлениях
image: bellamy/wallos:v5.8.3
container_name: wallos
restart: unless-stopped
# Привязываем порт строго к локальному интерфейсу 127.0.0.1 для защиты периметра
ports:
- "127.0.0.1:8282:80"
environment:
TZ: "Europe/Moscow"
volumes:
- ./db:/var/www/html/db
- ./logos:/var/www/html/images/uploads/logos
# Лимит памяти с 4-кратным запасом для пиковых задач парсинга логотипов и отчетов
mem_limit: 128m
cpus: 0.50
Рекомендация по версионированию для продакшена: фиксация конкретного релиза (например, v5.8.3) вместо плавающего тега latest страхует от внезапных изменений схемы базы данных при использовании утилит автообновления контейнеров вроде Watchtower. Переход на новые версии выполняется контролируемо: сначала создается горячий снимок wallos.db, затем меняется тег в манифесте и перезапускается сервис.
Сетевая изоляция: защита от обхода системного фаервола Docker
Обратите особое внимание на строку портов: 127.0.0.1:8282:80. Если указать просто 8282:80, Docker перехватит цепочку PREROUTING в iptables и откроет веб-интерфейс Wallos всему публичному интернету в обход UFW (подробнее этот механизм разобран в статье об обходе фаервола UFW контейнерами Docker). Привязка к адресу обратной петли 127.0.0.1 гарантирует, что доступ снаружи будет возможен строго через обратный прокси Nginx с шифрованием TLS.
Запустите контейнер в фоновом режиме:
sudo docker compose up -d
Проверьте статус запуска контейнера и фактическое потребление ресурсов утилитой docker stats:
sudo docker stats --no-stream wallos
В выводе команды вы увидите, что в состоянии покоя контейнер потребляет всего 20–30 МБ RAM. Заданный в манифесте лимит mem_limit: 128m гарантирует надежный 4-кратный запас для пиковых нагрузок: фоновой конвертации логотипов через библиотеки GD/WebP, формирования годовых финансовых отчетов и одновременного запроса валютных курсов.
4. Настройка обратного прокси Nginx с SSL-сертификатом Let's Encrypt
Для безопасного входа в веб-интерфейс через доменное имя (например, wallos.yourdomain.ru) настроим веб-сервер Nginx в качестве обратного прокси (Reverse Proxy) и выпустим бесплатный SSL-сертификат Let's Encrypt с автоматическим продлением.
Создайте конфигурационный файл виртуального хоста в каталоге Nginx:
sudo nano /etc/nginx/sites-available/wallos.conf
Вставьте следующую конфигурацию виртуального хоста (замените wallos.yourdomain.ru на ваш реальный поддомен):
server {
listen 80;
listen [::]:80;
server_name wallos.yourdomain.ru;
# Защита скрытых системных файлов (.git, .env)
location ~ /\. {
deny all;
}
# Максимальный размер загружаемых файлов (для пользовательских логотипов)
client_max_body_size 16M;
location / {
proxy_pass http://127.0.0.1:8282;
proxy_http_version 1.1;
# Заголовки проксирования для корректного определения схемы и клиента
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;
# Буферизация и таймауты
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
Активируйте виртуальный хост, создав символическую ссылку в каталоге sites-enabled, проверьте синтаксис Nginx и примените изменения:
sudo ln -s /etc/nginx/sites-available/wallos.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Выпустите бесплатный сертификат Let's Encrypt утилитой Certbot с автоматической настройкой редиректа на HTTPS в Nginx:
sudo certbot --nginx --redirect -d wallos.yourdomain.ru
Проверьте корректность цепочки SSL и дату продления
После выпуска сертификата убедитесь, что веб-сервер корректно отдает полную цепочку сертификатов (Full Chain), протокол HTTP/2 активен, а автоматический редирект на HTTPS не создает циклических петель перенаправлений. Проверить параметры можно онлайн в инструменте проверки SSL-сертификата.
5. Первоначальная настройка: валюты, обход ограничений ЕЦБ и автоматизация курсов ЦБ РФ
Откройте в браузере адрес https://wallos.yourdomain.ru. При первом посещении Wallos автоматически инициирует миграцию базы данных SQLite и откроет страницу регистрации первичной учетной записи администратора.
Придумайте надежный пароль (для генерации криптостойких комбинаций воспользуйтесь генератором надежных паролей) и выполните вход в личный кабинет. Далее перейдите в раздел настроек (иконка шестеренки «Settings» в левом меню).
1. Настройка валют и решение проблемы конвертации RUB в РФ
В подразделе Currencies настройте валюты учета. Для системного администратора в РФ типична ситуация, когда часть инфраструктуры оплачивается в рублях, а зарубежные серверы и API — в долларах или евро.
- Основная валюта (Main Currency): выберите
RUB (₽)— Российский рубль. - Дополнительные валюты: добавьте
USD ($)иEUR (€).
Ограничение Frankfurter для рубля: санкции и заморозка котировок ЕЦБ
Встроенный в Wallos бесплатный провайдер Frankfurter транслирует исключительно котировки Европейского центрального банка (ECB reference rates). С 1 марта 2022 года ЕЦБ официально приостановил публикацию курса евро к российскому рублю (EUR/RUB). В результате при выборе Frankfurter в качестве источника для RUB сервис возвращает ошибку 404 Not Found или 422 invalid currency: RUB, и автоматический пересчет в рубли не происходит.
Чтобы автоматическая мультивалютность стабильно работала в российских реалиях, есть два проверенных инженерных решения:
Способ А: Бесплатный API-ключ Fixer.io / APILayer (через веб-интерфейс)
Сервис Fixer.io продолжает отслеживать котировки российского рубля. Его бесплатный тариф (Free Plan) предоставляет 100 запросов к API в месяц. Так как Wallos обновляет курсы строго 1 раз в сутки (30 запросов в месяц), бесплатного лимита хватает с 3-кратным запасом. Зарегистрируйтесь на сайте fixer.io, скопируйте API-ключ, в настройках Wallos переключите провайдер на Fixer и сохраните токен.
Способ Б (Рекомендуемый): Автоматический импорт официального курса ЦБ РФ в SQLite
Наиболее надежный, автономный и независимый от зарубежных санкций метод — обновлять курсы валют напрямую из официальных данных Банка России. Вся база Wallos хранится в SQLite, а цена в основной валюте вычисляется как цена / rate. Соответственно, коэффициент пересчета равен 1 / курс_ЦБ.
Создайте на хосте автономный скрипт на Python 3 (использует только стандартные библиотеки, не требуя установки дополнительных пакетов):
sudo nano /opt/wallos/update_cbr_rates.py
Вставьте следующий код:
import urllib.request
import json
import sqlite3
import datetime
url = "https://www.cbr-xml-daily.ru/daily_json.js"
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
try:
with urllib.request.urlopen(req, timeout=10) as response:
data = json.loads(response.read().decode('utf-8'))
usd_rub = float(data['Valute']['USD']['Value'])
eur_rub = float(data['Valute']['EUR']['Value'])
# Wallos вычисляет цену в основной валюте как: price / rate
# Для рублей как главной валюты rate = 1 / курс_ЦБ
usd_rate = f"{1.0 / usd_rub:.6f}"
eur_rate = f"{1.0 / eur_rub:.6f}"
# Подключение к SQLite с таймаутом ожидания блокировок
conn = sqlite3.connect('/opt/wallos/db/wallos.db', timeout=15)
cursor = conn.cursor()
cursor.execute("UPDATE currencies SET rate = ? WHERE code = 'USD'", (usd_rate,))
cursor.execute("UPDATE currencies SET rate = ? WHERE code = 'EUR'", (eur_rate,))
cursor.execute("UPDATE currencies SET rate = '1.0' WHERE code = 'RUB'")
conn.commit()
conn.close()
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"[{now}] Курсы ЦБ РФ обновлены: USD={usd_rub:.2f} ₽ (rate={usd_rate}), EUR={eur_rub:.2f} ₽ (rate={eur_rate})")
except Exception as e:
print(f"Ошибка обновления курсов ЦБ РФ: {e}")
Добавьте запуск скрипта в системный crontab хоста ежедневно в 12:00 (сразу после публикации свежих котировок Центробанком):
(crontab -l 2>/dev/null; echo "0 12 * * * /usr/bin/python3 /opt/wallos/update_cbr_rates.py >> /var/log/wallos_cbr.log 2>&1") | crontab -
Архитектурная оговорка: особенности прямой модификации SQLite
Прямое обновление таблицы currencies через внешний скрипт — это эффективный прикладной метод решения проблемы санкций ЕЦБ и получения официального курса ЦБ РФ. Однако учитывайте, что этот подход работает в обход внутреннего кода приложения: перед выполнением мажорных обновлений Wallos обязательно создавайте резервную копию каталога /opt/wallos/db (согласно нашему скрипту бэкапа) и проверяйте неизменность структуры таблиц.
Замечание о версиях Wallos: поддержка сквозной авторизации OIDC появилась в Wallos начиная с релиза v4.0, а бесключевой провайдер Frankfurter интегрирован в ветке v5.x. Официальный образ bellamy/wallos:v5.8.3 содержит полный набор этих возможностей.
2. Создание категорий для системного администратора и вебмастера
В подразделе Categories настройте индивидуальную структуру расходов. Рекомендуется создать следующий базовый набор категорий с цветовой дифференциацией:
| Категория в Wallos | Цветовой маркер | Примеры отслеживаемых сервисов и списаний |
|---|---|---|
| VDS и Инфраструктура | #2563eb (Синий) |
Серверы VDS/VPS, виртуальный хостинг, объектные S3-хранилища, выделенные IP-адреса. |
| Доменные имена | #10b981 (Зеленый) |
Продление зон .RU, .РФ, .COM, .ORG с годовым или двухлетним циклом оплаты. |
| API и AI-сервисы | #8b5cf6 (Фиолетовый) |
Балансы OpenAI Platform, Anthropic API, транзакционные SMS-шлюзы и почтовые релеи. |
| Лицензии и CMS | #f59e0b (Оранжевый) |
Платные плагины WordPress, лицензии ISPmanager, коммерческие темы и подписки на IDE. |
6. Интеграция с Telegram Bot API: алерты о предстоящих списаниях
Ключевая практическая ценность Wallos заключается в том, что вам больше не нужно держать даты оплат в голове или вручную проверять календари. Система интегрируется с Telegram Bot API и заблаговременно присылает детальные сводки прямо в ваш мессенджер.
Для настройки интеграции выполните три простых шага:
- Создайте Telegram-бота: откройте диалог с официальным ботом
@BotFatherв Telegram, отправьте команду/newbot, задайте имя (например, «Infrastructure Billing Alert») и юзернейм (например,my_infra_bill_bot). Скопируйте выданный API-токен бота вида7123456789:AAH.... - Определите ваш Chat ID: запустите вашего нового бота кнопкой «Start» (
/start), затем напишите любое сообщение сервисному боту@userinfobot, чтобы узнать ваш уникальный числовой идентификатор (например,123456789). - Внесите данные в Wallos: в панели управления перейдите в Settings → Notifications, выберите вкладку Telegram, активируйте переключатель «Enabled», вставьте Token и Chat ID.
В блоке общих параметров уведомлений в поле Notify me X days before укажите количество дней до списания, за которое система должна сформировать предупреждение (для критически важных серверов и доменов оптимально выставить 3 или 7 дней, чтобы гарантированно успеть пополнить баланс или привязать резервную карту). Кроме того, при создании или редактировании любой конкретной подписки можно переопределить глобальное правило и настроить индивидуальный срок заблаговременного напоминания.
Нажмите кнопку Test Notification. Если всё настроено корректно, в ваш Telegram мгновенно придет тестовое сообщение от бота с подтверждением успешной связки.
Рекомендуемые VDS-провайдеры
Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с
Timeweb Cloud — Быстрые NVMe VDS
Оптимальный легковесный VDS для запуска Wallos и сопутствующих контейнеров. Мгновенная активация, почасовая оплата и защита от сбоев.
Selectel — Надежная облачная инфраструктура
Корпоративный уровень надежности для критически важных инфраструктурных сервисов с гарантированным аптаймом 99.98% в дата-центрах РФ.
Beget — Простота для вебмастеров и CMS
Удобная панель управления сервером, готовые шаблоны Docker и предсказуемая тарификация без скрытых переплат.
7. Автоматический бэкап базы данных SQLite на удаленное S3-хранилище
Так как вся информация о подписках, платежах, пользователях и истории транзакций хранится в локальном файле /opt/wallos/db/wallos.db, резервное копирование Wallos сводится к созданию консистентного снимка SQLite и его передаче на внешнее независимое хранилище (например, объектное S3-хранилище или резервный VDS).
Опасность простого копирования файла работающей базы SQLite
Категорически не рекомендуется выполнять простое копирование файла cp wallos.db backup.db при запущенном приложении. Если в момент копирования контейнер производит запись или выполняет транзакцию по обновлению курсов, результирующий файл окажется поврежденным (битым). Для получения целостной копии используйте официальную команду безопасного горячего снимка sqlite3 .backup.
Создайте каталог для локальных резервных копий и служебный bash-скрипт:
sudo mkdir -p /opt/wallos/backups
sudo nano /opt/wallos/backup.sh
Вставьте следующий проверенный скрипт создания резервных копий с ротацией за последние 14 дней:
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/opt/wallos/backups"
DB_FILE="/opt/wallos/db/wallos.db"
TIMESTAMP=$(date +"%Y-%m-%d_%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/wallos_backup_${TIMESTAMP}.db"
# Создание консистентного горячего снимка базы данных SQLite
sqlite3 "${DB_FILE}" ".backup '${BACKUP_FILE}'"
# Сжатие резервной копии утилитой gzip
gzip -9 "${BACKUP_FILE}"
# Удаление локальных копий старше 14 дней
find "${BACKUP_DIR}" -type f -name "wallos_backup_*.db.gz" -mtime +14 -delete
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Резервная копия базы Wallos успешно создана: ${BACKUP_FILE}.gz"
Сделайте скрипт исполняемым и добавьте его в системный планировщик cron хоста (выполняется ежедневно в 03:30 ночи):
sudo chmod +x /opt/wallos/backup.sh
(crontab -l 2>/dev/null; echo "30 3 * * * /opt/wallos/backup.sh >> /var/log/wallos_backup.log 2>&1") | crontab -
Для долгосрочного архивного хранения в изолированном контуре подключите автоматическую отправку архивов в S3 с помощью связки Restic и Autorestic, как описано в руководстве по автоматическим шифрованным бэкапам VDS на S3.
8. Инженерные рекомендации по безопасной эксплуатации и защите периметра
Поскольку финансовый трекер содержит полную структуру ваших серверов, доменов и затрат, безопасность доступа к веб-панели должна стоять на первом месте. Придерживайтесь следующих производственных рекомендаций:
- Ограничение доступа по белому списку IP (IP Whitelist): если ваша рабочая сеть или домашний провайдер имеет статический IP-адрес, закройте публичный доступ к поддомену
wallos.yourdomain.ruв Nginx. Достаточно добавить в блокserverдирективыallow 203.0.113.15; deny all;. В этом случае посторонние сканеры даже не увидят форму авторизации. - Двухфакторная аутентификация (2FA / TOTP): обязательно активируйте двухфакторную аутентификацию в профиле пользователя Wallos (Settings → Profile → Two-Factor Authentication). Сканируйте QR-код через Google Authenticator, Яндекс Ключ или Aegis. Без одноразового кода войти в панель будет невозможно даже при компрометации пароля.
- Единый вход через OIDC (Authelia / Keycloak): если в вашей инфраструктуре уже настроен шлюз единого входа, интегрируйте Wallos по протоколу OIDC без передачи паролей в само приложение (пошаговая настройка шлюза описана в инструкции по двухфакторной аутентификации Authelia и Nginx).
- Проверка открытых портов извне: убедитесь, что внутренний порт контейнера
8282не торчит в открытый интернет из-за особенностей маршрутизации Docker. Проверить доступность можно через утилитуnmapлибо с помощью онлайн-сканера портов.
Проверьте сетевой периметр и безопасность вашего сервера
Убедитесь, что внутренние порты контейнеров надежно изолированы, а публичные веб-интерфейсы отдаются исключительно через защищенный обратный прокси с валидным SSL-сертификатом.