mishkatik/infra-billing
mishkatik/infra-billing has 90 GitHub stars and 10 forks. Star changes are not measured yet. Last checked 2026-11-12 18:07 UTC. Last push 2026-11-12.
Self-hosted панель учёта расходов на инфраструктуру: автосинк серверов, балансов и платежей через API хостеров. Мультивалютность, прогнозы, Telegram-уведомления.
Measured star growth
- in 24h
- Update delayed
- in 7 days
- Update delayed
- in 15 days
- Update delayed
- in 1 month
- Update delayed
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
OriginalInfra Billing Panel
Персональная (single-user, self-hosted) панель учёта расходов на инфраструктуру: VPS, выделенные серверы, домены, CDN, объектные хранилища, лицензии и т.п. Панель сама ходит в API хостинг-провайдеров, тянет баланс аккаунта, список ресурсов, тарифы и даты списаний, складывает снапшоты и строит аналитику/прогнозы. Провайдеров без API владелец ведёт вручную.
Возможности
- Провайдеры с API: Timeweb Cloud, Hetzner Cloud, Hostkey (InvAPI), netcup, HostBill, ISPsystem BILLmanager, Selectel, 4VPS.SU, Netlen, Beget Cloud, Porkbun, Spaceship, Vultr, Linode, Aeza, VDSina, Cloudflare, StormWall, NetAngels, Yandex Cloud, Double Servers, OpenRouter, HostUp, HostVDS / CloudCore, DataPacket, Tube-Hosting, Gcore. Плюс Manual — провайдеры без API ведутся руками.
- Автосинк (по расписанию + кнопкой): баланс + валюта аккаунта, список серверов/услуг, даты следующих списаний; история баланса по дням (снапшоты).
- Импорт платежей там, где API отдаёт реестр: пополнения и списания (BILLmanager, Netlen, Vultr, Aeza, VDSina, Double Servers, HostVDS, Tube-Hosting, Gcore), пополнения и счета (Linode), оплаченные счета (HostBill, DataPacket), платежи (HostUp), потребление (Selectel, Yandex Cloud, OpenRouter), история биллинга (Cloudflare, best-effort). Ручные платежи — в журнале.
- Аналитика: месячные/годовые расходы, разрезы по провайдеру / стране / типу / валюте, прогноз по будущим списаниям, ближайшие списания с подсветкой критичности.
- Мультивалютность: суммы в своей валюте, конвертация к базовой; курсы ЦБ РФ или ручные.
- Telegram-уведомления (только исходящие): низкий баланс, скорое списание, ошибка синка. Доставка напрямую или через SOCKS5-прокси, если Telegram с сервера недоступен.
- Безопасность: аккаунт владельца создаётся при первом запуске; вход по паролю, passkey (WebAuthn) и/или Telegram (OpenID Connect) — методы переключаются в настройках; сессия — JWT в httpOnly-cookie; токены провайдеров шифруются AES-256-GCM. В списке и карточке провайдера секретов нет — только признак «задан»; показать их в открытом виде можно лишь по «глазику» в форме, из сессии владельца.
- MCP-сервер на
/api/mcp: любой MCP-клиент смотрит расходы, балансы и сервисы, а с токеном полного доступа — заводит сервисы и платежи и запускает синк.
RWP Shop
RWP Shop — лучший многофункциональный бот для VPN-коммерции на Remnawave:
личный кабинет клиента, платежи, подписки, поддержка, партнёрская программа и аналитика. Работает
в браузере и как Mini App в Telegram. Есть интеграция с Infra Billing.
Скидка 15% по промокоду MISH.
Стек
- Backend: NestJS 11 (Node 22) · Prisma 7 · PostgreSQL 18 · zod (
nestjs-zod) · axios · grammY - Frontend: Vite · React 19 · shadcn/ui · Tailwind CSS v4 · Golos Text · TanStack Query · axios
- Монорепо: npm-workspaces —
apps/backend,apps/frontend,packages/shared(общие zod-схемы) - Деплой: единый Docker-образ (бэкенд раздаёт API + собранный SPA) + отдельный Postgres
Установка (production)
Требования: Docker + Docker Compose plugin; домен и reverse-proxy с TLS (см. ниже — без HTTPS
вход не работает, т.к. сессионная кука Secure). Образ берётся из GHCR
(ghcr.io/mishkatik/infra-billing).
# 1. Каталог
mkdir -p /opt/infra-billing && cd /opt/infra-billing
# 2. Скачать prod-compose и пример конфига в .env
curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/mishkatik/infra-billing/main/docker-compose-prod.yml
curl -fsSL -o .env https://raw.githubusercontent.com/mishkatik/infra-billing/main/.env.example
# 3. Сгенерировать ключ шифрования (GNU sed; разделитель # — т.к. base64 содержит /)
sed -i "s#^ENCRYPTION_KEY=.*#ENCRYPTION_KEY=$(openssl rand -base64 32)#" .env
# 4. Пароль БД — один и тот же в POSTGRES_PASSWORD и в DATABASE_URL
pw=$(openssl rand -hex 24) && sed -i "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$pw/" .env && sed -i "s|^\(DATABASE_URL=\"postgresql://infra:\)[^\@]*\(@.*\)|\1$pw\2|" .env
# 5. Запуск (миграции применяются на старте)
docker compose up -d && docker compose logs -f
При первом открытии панель покажет экран регистрации — создайте аккаунт владельца (логин + пароль; passkey можно добавить позже).
Панель поднимется на 127.0.0.1:8080. Дальше — reverse-proxy с TLS на ваш домен.
Reverse proxy + TLS (обязательно)
Контейнер слушает только 127.0.0.1:8080 — наружу не торчит. Поставьте перед ним reverse-proxy,
который терминирует TLS. Без HTTPS логин не сработает (сессионная кука помечена Secure).
Пример Caddy (сам выпустит сертификат):
billing.example.com {
reverse_proxy 127.0.0.1:8080
}
Caddy по умолчанию не ограничивает ожидание ответа бэкенда. В прокси, где такой лимит есть,
поднимите его до ≥ 120s — ручной синк всех провайдеров может отвечать до ~2 минут
(в nginx это proxy_read_timeout, по умолчанию 60s).
Обновление
Миграции базы применяются при старте нового образа и назад не откатываются, поэтому перед обновлением сделайте дамп и запомните текущую версию (она рядом с названием «Infra Billing» в боковом меню):
cd /opt/infra-billing && mkdir -p backups
docker compose exec -T infra-billing-db sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' > backups/infra_billing-$(date +%Y%m%d-%H%M).dump
Токены провайдеров в дампе зашифрованы ключом ENCRYPTION_KEY из .env — без него их не
восстановить, поэтому храните .env вместе с дампами.
Обновить и перезапустить:
cd /opt/infra-billing && docker compose pull && docker compose down && docker compose up -d && docker compose logs -f
Почистить неиспользуемые образы:
docker image prune
Откат на прошлую версию
Повторный docker compose pull не поможет: :latest уже указывает на новую версию, а прошлая может
не запуститься на базе после новых миграций. Верните базу из дампа и закрепите прошлую версию образа:
cd /opt/infra-billing
# 1. Остановить панель и пересоздать базу из дампа (подставьте имя своего файла из backups/)
docker compose stop infra-billing
docker compose exec -T infra-billing-db sh -c 'dropdb -U "$POSTGRES_USER" "$POSTGRES_DB" && createdb -U "$POSTGRES_USER" "$POSTGRES_DB"'
docker compose exec -T infra-billing-db sh -c 'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --no-owner' < backups/infra_billing-ГГГГММДД-ЧЧММ.dump
# 2. Закрепить прошлую версию (например, 0.47.0) и поднять панель
sed -i 's#image: ghcr.io/mishkatik/infra-billing:.*#image: ghcr.io/mishkatik/infra-billing:0.47.0#' docker-compose.yml
docker compose up -d
Чтобы снова получать обновления, верните в docker-compose.yml тег :latest.
PostgreSQL 17 → 18 (с 0.44.0, не обязательно, но рекомендуется)
С 0.44.0 compose в репозитории использует postgres:18 и монтирует том в /var/lib/postgresql
(раньше — /var/lib/postgresql/data). Переходить не обязательно: приложение работает и с
PostgreSQL 17 — достаточно не трогать свой docker-compose.yml и обновлять только образ панели
(docker compose pull). Но обновиться рекомендуется, чтобы не отставать от поддерживаемых версий
и от compose-файла в репозитории. Файлы 17-й версии новый сервер сам не подхватит — данные надо
обновить на месте, это делает образ pgautoupgrade:
# 1. Дамп на всякий случай
docker compose exec -T infra-billing-db sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' > infra_billing-pg17.dump
# 2. Скачать новый compose (в нём уже postgres:18 и новый путь тома)
curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/mishkatik/infra-billing/main/docker-compose-prod.yml
# 3. Временно поставить у сервиса infra-billing-db образ pgautoupgrade и прогнать апгрейд
sed -i 's#image: postgres:18.*#image: pgautoupgrade/pgautoupgrade:18.6-trixie#' docker-compose.yml
docker compose down && docker compose up -d infra-billing-db && docker compose logs -f infra-billing-db
# (ждать «database system is ready to accept connections» после «End of reindexing»)
# 4. Вернуть официальный образ и поднять всё
sed -i 's#image: pgautoupgrade/pgautoupgrade:.*#image: postgres:18.6#' docker-compose.yml
docker compose down && docker compose pull && docker compose up -d
Вход в систему
Аккаунт владельца создаётся при первом запуске прямо в панели — на экране регистрации (логин + пароль; там же можно сгенерировать стойкий пароль и сразу скопировать его).
Экран регистрации доступен без авторизации, пока админ не создан. Пройдите настройку сразу после деплоя и не открывайте панель в интернет до этого — иначе аккаунт может занять тот, кто откроет её первым.
Способы входа — пароль, passkey (WebAuthn: Touch ID / Windows Hello / аппаратный ключ) и Telegram (OpenID Connect). Это альтернативы, а не второй фактор — достаточно любого включённого. Управление — Настройки → Вход в систему: тумблеры «Пароль» / «Passkey» / «Telegram», добавление и удаление passkey-ключей, привязка Telegram. Хотя бы один рабочий способ всегда остаётся включённым (защита от блокировки).
Passkeys работают только в защищённом контексте (HTTPS или localhost). В настройках passkey
задайте rpId (домен без https://) и Origin (полный адрес) — кнопка «Подставить текущий
хост» заполнит их автоматически.
Вход через Telegram настраивается в BotFather: бот → Web Login → Switch to OpenID
Connect Login. Там же берутся Client ID и Client Secret — это отдельное значение, не
токен бота. В Allowed URLs внесите адрес панели и Redirect URL
(<адрес панели>/api/auth/telegram/callback; на странице настроек его можно скопировать).
Затем в панели укажите «Адрес панели» (кнопка «Текущий адрес»), Client ID и Client Secret,
сохраните и нажмите «Привязать Telegram» — входить сможет только привязанный аккаунт. Смена Client
ID, Secret или адреса сбрасывает привязку.
Восстановление доступа (забыли пароль)
Если вход по паролю выключен, а passkey или Telegram недоступны, — сначала верните вход по паролю. Passkey и привязка Telegram сохранятся:
docker compose exec infra-billing cli enable-password
Если и сам пароль утерян — сбросьте администратора. Это удалит логин, пароль, все passkey и привязку Telegram; панель снова покажет экран первичной настройки.
# Интерактивное меню:
docker compose exec -it infra-billing cli
# Либо сразу, без подтверждения:
docker compose exec infra-billing cli reset-admin --yes
Конфигурация (.env)
| Переменная | Назначение |
|---|---|
PORT |
Порт бэкенда (он же отдаёт SPA), default 8080 |
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB |
Параметры контейнера Postgres |
POSTGRES_HOST_PORT |
Порт публикации Postgres на 127.0.0.1 (default 5432) |
DATABASE_URL |
Строка подключения Prisma (хост = infra-billing-db в docker, 127.0.0.1 локально) |
ENCRYPTION_KEY |
Обязательно. AES-256-GCM ключ для секретов в БД — токены провайдеров, секрет сессии и Client Secret входа через Telegram (32 байта base64). После смены ключа Client Secret нужно ввести заново |
DOCS |
true — включить Swagger UI на /api/docs (публично при включении). Default false |
COOKIE_SECURE |
Secure-флаг сессионной куки. Не задан — следует за NODE_ENV (в prod включён). false — только для http-деплоя за защищённым транспортом (Tailscale/NetBird); passkeys всё равно требуют https |
API-доступ
Панель отдаёт тот же REST API, что использует фронтенд. Для программного доступа создайте токен:
Настройки → API токены → Добавить (имя и доступ), затем копируйте токен. Запросы — с заголовком
Authorization: Bearer <token>:
curl -H "Authorization: Bearer ib_…" https://infra-billing/api/providers
Каждый провайдер приходит с массивом accounts[] (у каждого аккаунта свои креды, баланс и синк)
и суммами balances[] по валютам; аккаунт правится через /api/provider-accounts/{uuid}.
Доступ токена выбирается при создании:
- только чтение (по умолчанию) — только
GET-запросы, на остальное токену отвечают 403; - полный — всё, что есть в API: провайдеры, сервисы, платежи, синк, настройки, аналитика.
Ни один токен не видит секреты провайдеров и не управляет входом и другими токенами: это доступно только из сессии владельца. Токены, созданные до появления выбора, — с полным доступом.
MCP
Панель — MCP-сервер (Streamable HTTP) на https://<панель>/api/mcp, авторизация тем же токеном.
В конфиге клиента, который поддерживает удалённые серверы с заголовками:
{
"mcpServers": {
"infra-billing": {
"url": "https://infra-billing.example.com/api/mcp",
"headers": { "Authorization": "Bearer ib_…" }
}
}
}
Сервер отдаёт три инструмента: list_operations (каталог доступных операций), describe_operation
(параметры, тело и ответ одной операции в JSON Schema) и call_operation (вызов). Операции —
обёртки над REST API, поэтому ограничения токена те же: токен «только чтение» видит и вызывает
только чтение. Удалить провайдера или аккаунт, слить провайдеров и поменять настройки через MCP
нельзя — это делается в панели. Каждый вызов пишется в лог ([MCP] <токен>: <операция> → <статус>).
Провайдеры — где взять доступ
Добавление: Провайдеры → Добавить, выбрать тип, ввести токен/креды (шифруются, в API не возвращаются). После сохранения провайдер сразу синкается.
- Timeweb Cloud — ЛК → «API и Terraform» → создать токен.
- Hetzner Cloud — Project → Security → API Tokens (read). Баланса/счетов/платежей в API нет — синкаем серверы, месячный cap тарифа, страну и синтетическую дату списания (1-е число следующего месяца) для upcoming-алертов.
- Hostkey — InvAPI (
invapi.hostkey.ru) → меню пользователя → API-ключи. Тянет credit-баланс (WHMCS), серверы сprebill_rate/ периодом и синтетическую дату списания (1-е число следующего месяца). Реестр платежей в v1 не импортируется. - netcup — кнопка «Авторизоваться через netcup» в форме: войдите в SCP в браузере и подтвердите (OAuth2 device flow, токен подтянется сам). Баланса/цен/списаний в API нет — только серверы (страна определяется по дата-центру).
- HostBill — base URL вашей инсталляции (напр.
https://secure.veesp.com/api) + email + пароль. - ISP BILLmanager — base URL (
https://.../billmgr) + логин + пароль (+ TOTP-секрет, если 2FA по OTP). Если хостер закрыл вход в API капчей (например, FirstVDS), панель сама переключается на stateless-авторизациюauthinfo. Для неё добавьте IP сервера панели в список разрешённых — у FirstVDS это «Доступ к API» в настройках биллинга — иначе синк упадёт с ошибкойforbidden_auth_method. 2FA в этом режиме не работает (нет сессии для подтверждения кода) — отключите её у такого хостера. - Selectel — номер аккаунта + сервисный пользователь IAM (имя + пароль) с ролью
«Наблюдатель» (
reader): она даёт баланс, потребление и список бакетов (роли «Биллинг» для бакетов мало); опц. имя проекта Облачной платформы — для облачных серверов, роутеров и бакетов S3. Стоимость каждого — среднее потребление в сутки за последние 7 дней (у сервера — вместе с его дисками и публичными IP). - 4VPS.SU — API-ключ (ЛК → раздел API) + id панели (обычно
1). - Netlen — API-ключ (панель → раздел API). Важно: добавьте IP сервера в whitelist ключа, иначе
запросы отклоняются (
NO_IP_WHITELISTED). Баланс, серверы (цена в USD) и реестр транзакций (пополнения/списания) — всё из API. - Beget Cloud — логин аккаунта cp.beget.com + пароль (новый Cloud API, JWT). Опц. TOTP-секрет, если включена 2FA по приложению, и отдельный «API-пароль» из панели (Аккаунт → Безопасность → Beget API) — он включает синк баланса. Тянет VPS и облачные сервисы (БД/S3/CDN), цены в RUB; истории платежей и дат списаний в API нет.
- Porkbun — API key + Secret API key (Account → API Access; ключ нужно включить на каждом домене).
Регистратор доменов: тянет домены (
type=domain, дата продления = дата истечения), баланс (USD) и цену продления по TLD. Истории платежей в API нет. - Spaceship — API key + secret (API manager). Регистратор доменов: тянет домены (
type=domain, дата продления = дата истечения). Баланса, цен продления и истории платежей в API нет — цену домена можно проставить руками. - Vultr — API-ключ (Account → API). Если на ключе включён Access Control — добавьте IP сервера в whitelist, иначе запросы отклоняются (403). Тянет баланс (USD), серверы (цена из тарифа) и реестр billing-history (пополнения и списания); страна определяется по региону.
- Linode (Akamai) — Personal Access Token (Account → API Tokens; доступ на чтение к Account и
Linodes). Тянет серверы (цена из тарифа, с учётом региональных цен), баланс (USD) и историю
платежей (пополнения + счета). Linode постоплатный:
balance— это задолженность, поэтому храним чистую позицию (кредит — плюс, долг — минус). Страна определяется по региону. - Aeza — API-ключ (панель → API Keys). Тянет серверы (цена по сроку оплаты, страна по локации, дата продления), баланс (валюта аккаунта — RUB/USD/EUR) и историю транзакций (пополнения + списания). Суммы в API — в минорных единицах (÷100). Баланс предоплатный.
- VDSina — постоянный API-токен из личного кабинета (список пользователей:
https://cp.vdsina.ru/user/list). Тянет баланс основного счёта (RUB), серверы и операции по балансу (оплаченные пополнения + списания). - Cloudflare — API-токен (My Profile → API Tokens) с правами Registrar: Domains:Read
и Billing:Read, плюс ID аккаунта (из URL дашборда или
GET /accounts). Регистратор доменов: тянет домены (type=domain, годовой период, дата продления = дата истечения; цены в API нет → вводятся вручную) и историю биллинга (пополнения/списания, USD). Баланса в API нет (постоплата через Stripe); Billing API устарел, поэтому импорт платежей best-effort. - StormWall — API-ключ (личный кабинет → API-ключ). DDoS-защита/WAF: баланса, цен и платежей
в API нет вообще (услуги вводятся с ценой вручную) — тянет только список услуг (
/v3/services), для защищённых доменов — их реальное имя. - Yandex Cloud — авторизованный ключ (JSON) сервисного аккаунта целиком: в консоли создать
сервисный аккаунт, выдать ему
viewerна папку (инвентарь) иbilling.accounts.viewerна биллинг-аккаунт (баланс и расходы), затем «Создать авторизованный ключ» — не статический ключ доступа. Папку и биллинг-аккаунт панель определяет сама и показывает бейджами прямо в форме. Тянет только Compute-инстансы (управляемые БД, бакеты, k8s в инвентарь не попадают), баланс биллинг-аккаунта и историю потребления по дням. Цен в Compute API нет — стоимость считается из отчёта потребления, а он отдаётся не чаще 1 запроса в минуту, так что на аккаунте с несколькими серверами цена и история могут подтянуться не с первого синка. - Double Servers — email + пароль от ЛК (
doubleservers.com/login). Опц. TOTP-секрет, если включена 2FA по приложению. Тянет баланс (EUR), VPS (цена, дата продленияexpires_at) и историю: пополнения (/api/billing/history) + списания по серверам (/api/servers/{id}/history). Публичного API-токена нет — синк логинится в панель. - OpenRouter — Management API key (openrouter.ai → Settings → Management Keys). Обычный
inference-ключ не подойдёт: синк проверяет его через
/keyи отклоняет с явной ошибкой. LLM-агрегатор, серверов у него нет — панель заводит по услуге (type=llm) на каждую модель, по которой был трафик. Цена услуги — фактический расход: за текущий месяц, а пока в нём трат нет — за всё окно/activity(последние ~30 суток UTC, посуточно). Оттуда же импортируются списания — по записи на «модель + день»; пополнений в API нет, поэтому в журнале только расход. Баланс — остаток купленных кредитов (/credits: пополнено − потрачено, USD). Названия моделей подставляются из каталога/models(тумблер «Имена из каталога» в форме; выключить — останутся слаги видаanthropic/claude-sonnet-5), вендор берётся из слага и показывается иконкой. - HostUp — API-ключ (
cloud.hostup.se/api-management) со scoperead:allили наборомread:billing,read:services,read:vm,read:domains. Безread:servicesсписок VPS приходит пустым, безread:domainsдомены пропускаются (в логе — предупреждение). Тянет кредитный баланс аккаунта (SEK, или EUR, если аккаунт в евро), VPS (цена и цикл оплаты, дата списания — срок неоплаченного счёта, а если его нет — день после оплаченного периодаpaidThroughDate), cPanel-хостинг (type=other) и домены (дата списания —nextDueAt, срок счёта на продление). Полугодовой цикл приводится к месячной цене, 2–3 года — к годовой. Локации VPS в API нет — страну проставьте руками. Импортируются проведённые платежи живыми деньгами (карта, Swish, Bankgiro, SEPA…) как пополнения; оплата счёта из кредита и возвраты не импортируются. Pay-as-you-go Cloud VPS синкаются без цены. - HostVDS / CloudCore — логин и пароль OpenStack из панели (аккаунт → вкладка «API» → «OpenStack
Dashboard», логин вида
hostvds-…), не вход на сайт. Обе марки — одна панель; для CloudCore укажите base URLhttps://cloudcore.ru. Тянет серверы всех регионов: страна по региону, цена — месячная цена тарифа из публичного каталога плюс платный тариф сети, в валюте региона (EUR/USD, у CloudCore — RUB). Сверх пакета трафик не учитывается. Баланс и платежи — по желанию: email и пароль входа на сайт (+ TOTP-секрет, если включена 2FA); тогда тянутся баланс (USD), пополнения и списания — одно в день на сервер, с привязкой к услуге. Без них баланса нет (как у Hetzner). - DataPacket — API-ключ (клиентская панель → Security → Add API key; достаточно read-only).
GraphQL API: тянет подписки — каждый сервер отдельной услугой (
type=dedicated, цена — его позиция в подписке, страна по локации), а прочие регулярные позиции подписки (IP, трафик, DDoS, сборы) — одной услугой на подписку: в API у них нет id и привязки к серверу. Период и дата списания — изbillingCycleподписки (месяц/квартал/год; дневной биллинг — постоплата без даты). Импортируются оплаченные счета как пополнения (сумма с НДС, дата оплаты); счета, оплаченные с баланса DataPacket или кредит-нотой, пропускаются. Баланса аккаунта в API нет. - Tube-Hosting — email + пароль от
cp.tube-hosting.com(API-ключей нет — синк логинится в JSON API панелиapi.tube-hosting.com). Опц. TOTP-секрет, если на аккаунте подтверждена 2FA через приложение. Тянет баланс (EUR), группы услуг — по услуге на группу (сервер вместе с IPv4/трафик-бандлом; цена — сумма услуг группы, дата списания — оплаченный доruntime, период изruntimeInterval, 30 дней → месяц) и журнал: пополнения (PayPal, карта…) и списания за продления, привязанные к своей группе. Локации в API нет — страну проставьте руками. - Gcore — постоянный API-токен (портал → Profile → API tokens; заголовок
APIKey). Деньги берутся из биллингового журнала аккаунта (/billing/client/v1; документированный/billing/org/v1— только для реселлеров): баланс, оплаты картой (пополнения) и списания — по записи на позицию биллинга за день, окно 31 день. Услуги: с ролью токена Administrators — из Cloud cost report, по услуге на сервер вместе с подключёнными дисками и IP (страна по региону); с более узкой ролью (например, Users) Cloud недоступен — тогда по услуге на позицию биллинга («Instance … Frankfurt», «Block Storage …»). Цена — расход за последние 7 дней, приведённый к 30 дням. Оплата pay-as-you-go: дат списаний нет. Не-Cloud продукты (CDN и т.п.) — всегда по позициям биллинга. - Manual — без API, всё вводится руками.
Telegram-уведомления
- Создать бота у @BotFather, получить токен.
- Узнать свой chat id (например, через @userinfobot), боту нажать
/start. - В панели Настройки → Telegram — токен + chat id (опц. id топика), сохранить. Кнопка «Отправить примеры» пришлёт по образцу каждого типа уведомления. Изменения — без рестарта.
- SOCKS5-прокси (опционально) — если Telegram с сервера недоступен напрямую, в том же
разделе укажите прокси:
socks5h://user:pass@host:1080(логин/пароль — только если прокси требует аутентификацию). Рекомендуемая схема —socks5h(DNS-имя резолвит сам прокси); со схемойsocks5имя резолвится локально и прокси получает голый IP — часть прокси такие CONNECT-запросы молча отбрасывает. Пустое поле — отправка напрямую. Таймаут запроса к Telegram — 10 секунд, ошибки доставки видны в логах контейнера.
Локальная разработка
Команды — через Task (brew install go-task), task без
аргументов покажет список.
task install # npm ci
task db-up # поднять только Postgres (127.0.0.1:5432)
# .env для локального запуска вне docker — DATABASE_URL на 127.0.0.1:
# DATABASE_URL="postgresql://infra:[email protected]:5432/infra_billing?schema=public"
task migrate # prisma migrate dev
task dev # backend :8080 + frontend :5173 (Vite проксирует /api)
Открыть http://localhost:5173. task migrate/task studio сами ходят в БД на 127.0.0.1
(см. LOCAL_DATABASE_URL в Taskfile.yml). Локальный билд образа: task docker-build +
task docker-up (использует docker-compose.yml со сборкой из исходников).
Превью дашборда в шапке README обновляются так (нужны запущенные task dev и креды владельца):
# один раз, если нет системного Chrome: npx playwright install chromium
CAPTURE_USER=admin CAPTURE_PASSWORD='…' task docs-screenshot
Скрипт пишет docs/screenshot-{dark,light}.webp (Retina → рамка → WebP).
Explore related projects
awesome-selfhosted/awesome-selfhosted
A list of Free Software network services and web applications which can be hosted on your own servers
336,615 starsimmich-app/immich
High performance self-hosted photo and video management solution.
119,024 starsStirling-Tools/Stirling-PDF
#1 PDF Application on GitHub that lets you edit PDFs on any device anywhere
96,434 starslouislam/uptime-kuma
A fancy self-hosted monitoring tool
93,575 stars