debudLeg

debudLeg

Дебажу код,отлаживаю жизнь https://t.me/debug_leg
На Пикабу
115 рейтинг 8 подписчиков 1 подписка 68 постов 0 в горячем

В 3 ночи мой бот уверенно перепутал «колики» и «голод». Я всё равно его выпустил — и вот почему

В 3 ночи мой бот уверенно перепутал «колики» и «голод». Я всё равно его выпустил — и вот почему

Я сделал Telegram-бота, который по короткому фрагменту детского плача (в MVP беру 5 секунд) пытается угадать причину из 6 классов и быстро вернуть ответ. Это не диагностика: бот может ошибаться, а шум и контекст ломают предсказание сильнее, чем хочется.

Что именно предсказываем

Сейчас бот возвращает один наиболее вероятный класс:

  • Боль в животике

  • Колики

  • Дискомфорт

  • Усталость

  • Голод

  • Страх

Честная оговорка: в реальности причины могут накладываться, а некоторые классы пересекаются по смыслу (например, «колики» vs «боль в животике»), поэтому это классификация по разметке, а не “понимание ребёнка”.

Архитектура без воркера: очередь в Postgres + cron

Я не держу постоянно работающий воркер. Задачи на обработку копятся в Postgres‑очереди, а по расписанию их разгребает cron прямо в базе: достаёт пачку задач, отправляет их в Flask-инференс, сохраняет результат и помечает задачу выполненной.

Telegram -> бот

| кладём задачу {voice_url, request_id, ...}

v

Supabase Postgres

- очередь pgmq: cry_jobs

- таблицы: requests / predictions / errors

^

| pg_cron по расписанию: read batch -> HTTP -> write result

|

Flask inference API

- скачать голосовое

- препроцессинг (5s, mel)

- CNN predict

- ответ + запись результата

Supabase Cron работает на расширении pg_cron: расписание хранится в cron.job, а история прогонов — в cron.job_run_details. Очередь — это pgmq: чтение сообщений задаёт visibility timeout (пока задача “в работе” она невидима), а после успеха сообщение нужно удалить (pgmq.delete) или архивировать (pgmq.archive), иначе оно вернётся в очередь после истечения окна.

Как я разгребаю очередь (вот что реально важно)

Суть тут не в “красивом SQL”, а в трёх правилах, без которых ты быстро утонешь:

  • Пачка: cron‑задача читает ограниченное число сообщений через pgmq.read(queue, vt, qty) и обрабатывает их за один запуск, чтобы не упираться в таймауты и не выстрелить себе в ногу.

  • Повторы: если инференс/сеть упали и вы не сделали delete/archive, сообщение снова станет видимым после vt — значит, дубликаты будут.

  • Идемпотентность: результат пишется по уникальному request_id (UPSERT/“записать один раз”), иначе повторная доставка начнёт плодить мусор и ломать статистику.

Если в системе есть только одна вещь “как у взрослых” — пусть это будет идемпотентность.

Где Supabase, а где модель

Supabase у меня — это Postgres и два расширения вокруг фоновых задач: очередь (pgmq) и планировщик (pg_cron). Модель живёт отдельно в Flask: сервис принимает ссылку на голосовое, скачивает её, делает препроцессинг и отдаёт вероятности по 6 классам, а я сохраняю результат в базу и отвечаю пользователю.

ML: baseline mel + CNN (почему так)

Я сделал максимально прямолинейный baseline, чтобы быстро выйти в “работает end‑to‑end”:

  • Аудио привожу к SAMPLE_RATE = 22050, беру фиксированное окно DURATION = 5 секунд (короткое дополняю нулями).

  • Строю mel‑спектрограмму (N_MELS=128), перевожу в dB через librosa.power_to_db(..., ref=np.max), и привожу временную ось к MAX_TIME=200.

  • Дальше CNN: три блока Conv+Pool (32/64/128) → Dense(128) + Dropout(0.5) → Softmax.

5 секунд я выбрал как компромисс между UX и стабильностью входа: проще стандартизировать форму тензора и быстрее отвечать пользователю.

Данные и ответственность

Сейчас я не храню аудио пользователей: файл нужен только на время обработки и ответа. Дальше я хочу улучшать модель, но сбор аудио для дообучения возможен только как отдельный opt‑in с понятными сроками хранения и удалением по запросу — иначе доверия не будет.

И ещё: если у ребёнка есть тревожные симптомы (температура, вялость, отказ от еды и т.п.), бот не должен быть точкой принятия решения — это надо проговаривать в тексте прямо, иначе вы выглядите безответственно.

Где это ломается (и что буду чинить первым)

  • Шум/эхо и агрессивная обработка микрофоном телефона меняют спектрограмму сильнее, чем кажется.

  • В реальности “причина” может быть не одна, но модель всегда выбирает один класс.

  • Пересечение классов делает ошибки неизбежными — поэтому нужен режим “не уверен” и предложение перезаписать в тишине.

Вопрос к читателям (выберите A/B/C)

Мне нужен совет по двум решениям — выберите вариант в комментариях:

  1. Дообучение и данные:

  • A) Только opt‑in + пользователь выбирает “что было на самом деле” (дороже по UX, но лучшая разметка).

  • B) Только opt‑in + кнопки “угадал/не угадал” (хуже разметка, выше конверсия).

  • C) Не собирать аудио вообще, улучшать только препроцессинг и правила отказа.

  1. Что первым даст прирост качества:

  • A) VAD/проверка качества входа (шум, клиппинг, доля плача) + “не уверен”.

  • B) Аугментации под шум/микрофоны.

  • C) Менять модель (CRNN/Transformer) раньше, чем чинить данные.

Если вы делали аудио‑ML в проде: где я гарантированно наступлю на грабли?

Если хотите смотреть, как это всё развивается (и где оно снова развалится), я веду Telegram‑канал про разработку/продукт и этот проект: t.me/debug_leg. Туда же кидаю мелкие апдейты

Показать полностью 1
1

А ты доверяешь своему проекту?

А ты доверяешь своему проекту?

Для Cursor или любого другого VSCode‑форка есть ненулевая вероятность, что при открытии чужой репы IDE тихо запустит какие‑нибудь скрипты в фоне.

Недавно наткнулся на историю: человек скачал репозиторий с автономным ИИ‑агентом "просто посмотреть код", открыл папку в Cursor и IDE сразу сама запустила какие‑то node‑скрипты в терминале. Без единого клика. Спасло его только то, что данные были зашифрованы, пароли в менеджере, а крипта в холодном кошельке.

Откуда вообще берётся риск

В классическом VSCode есть Workspace Trust — та самая модалка "доверяете ли вы этому воркспейсу?", от ответа зависит, можно ли запускать расширения и скрипты.

Есть Tasks с режимом runOn: folderOpen, который позволяет запускать скрипты при открытии папки. Удобно для честной автоматизации и идеально для атаки.

В чистом VSCode это завязано на trust. А вот в Cursor, по их же документации, workspace trust по умолчанию отключён и никакого лишнего вопроса вы просто не увидите.

В результате злоумышленнику достаточно положить в репозиторий tasks, которые стартуют при открытии папки, и дождаться, пока кто‑то откроет эту репу в форке с выключенным trust. Node‑скрипт в таске имеет доступ к ОС, а дальше полёт фантазии, от телеметрии до кражи ключей.

Что можно сделать прямо сейчас

Минимальный чек‑лист:

включить workspace trust;

отключить автоматический запуск tasks.

В settings JSON это две строки:

"security.workspace.trust.enabled": true,

"task.allowAutomaticTasks": "off"

После того как прочитал эту историю, первым делом пошёл и проверил свои настройки IDE.

Если такие практичные разборы про разработку, безопасность и реальные кейсы из проектов заходят — у себя в Telegram‑канале регулярно разбираю подобные штуки и показываю, как это влияет на живые продукты. Ссылка на канал.

Показать полностью 1
1

Железо в ипотеку: почему разработчикам снова придётся считать память

Железо в ипотеку: почему разработчикам снова придётся считать память

Друг недавно пошёл купить планку памяти на 16 ГБ и вернулся с ощущением, что железо скоро будут продавать в ипотеку.

Он зацепился за простую мысль: оперативка есть везде — в компьютерах, телефонах, приставках, серверах. Если память дорожает, значит очень быстро подорожает всё остальное железо.

Для разработчиков это неприятный звоночек. На мобилках и десктопах подход «и так сойдёт, железо вывезет» будет работать хуже: более дешёвые устройства, больше экономии на начинке — значит, снова придётся думать про оптимизации, вес приложений, количество абстракций и то, что реально нужно тащить в рантайм.

На бэке привычное временное решение «завалим проблему железом» (которое по традиции становится постоянным) тоже перестаёт быть очевидным. Если память, GPU и виртуалки дорожают, то горизонт «давайте просто докинем ещё один инстанс» превращается в всё более дорогой вид спорта.

С другой стороны, на всё это сверху уже наезжает волна сервисов и приложений на LLM, сделанных без особых мыслей про ресурсы. Если виртуалки и GPU подорожают, LLM‑API, скорее всего, тоже станут дороже, а значит, экономика части проектов, построенных по принципу «шлём всё в большую модель и не паримся», может просто перестать сходиться.

Разработка в итоге снова превращается в честный анализ критериев: что считать локально, что кешировать, какую модель брать, что выкинуть, чтобы продукт вообще жил в плюс, а не работал в минус ради красивых демо.

Вопрос к читателям: если железо и облака ещё подорожают, вы скорее пойдёте в жёсткую оптимизацию всего или просто заложите рост себестоимости в цену продукта?

Если такие разборы интересны, в Telegram делюсь ещё и практикой: как считаю экономику своих фич и LLM‑штук на реальных проектах.

Показать полностью 1
0

Метод шести шляп: как принять решение

Метод шести шляп: как принять решение

Инди‑разработчик одновременно пишет код, рисует иконки, настраивает аналитику и считает, хватит ли выручки, чтобы дожить до следующего релиза. В голове при этом орут шесть голосов — от художника‑перфекциониста до паникёра, который шипит: «не лезь в серяк, всё сломаешь». Недавно я это сполна почувствовал, когда на финальной прямой запуска моего расширения для Chrome под Европу Google заблокировал рекламный кабинет — весь запуск был заточен под поисковый трафик, и в один момент канал просто исчез.

Кейс: Google Ads хлопнул дверью

Расширение жило за счёт идеи: забираем тёплый поисковый трафик из Google Ads, ведём на продукт, дальше монетизируем. Аудитория — Европа, так что нормальной альтернативы Google по объёму и качеству трафика, по сути, нет. На финальной части запуска, когда оставалось включить бюджеты и смотреть на конверсии, рекламный кабинет схлопнулся по политике: без внятных объяснений, с размытыми формулировками и стандартной отпиской.

В голове мгновенно нарисовались четыре сценария:

  • спорить с Google и пытаться выбить разбан через апелляции;

  • купить новый кабинет у агентства;

  • залезть в прокси/серяк с «арендованными» аккаунтами;

  • переписать продукт под другой источник трафика (например, Яндекс), хотя целевая аудитория живёт в Европе.

И вот тут во мне в полный голос заговорили все внутренние персонажи — от паникёра до художника. Чтобы не принимать решение «на ощущениях», я вытащил метод шести шляп.

Что за метод и зачем он инди

Метод шести шляп — это техника Эдварда де Боно, где мышление делится на шесть режимов: факты, эмоции, риски, выгоды, креатив и модерацию. Вместо того чтобы держать всё в голове одновременно и метаться, ты по очереди «надеваешь» шляпы и смотришь на одну и ту же ситуацию под разными углами.

Для инди‑разработчика это особенно полезно: обычно решения принимает либо внутренний паникёр (чёрная шляпа), либо вдохновлённый художник (зелёная/красная), а белая и жёлтая — факты и выгоды — просто молчат.

Классика такая:

  • Белая — факты и цифры.

  • Красная — эмоции и чуйка.

  • Чёрная — риски и «что пойдёт не так».

  • Жёлтая — выгоды и «что пойдёт так».

  • Зелёная — варианты и идеи.

  • Синяя — модератор, который собирает всё в план.

Ниже — как я разобрал свою блокировку Google Ads по этим шляпам.

Шаг 1. Белая шляпа: что есть на столе

Сначала — сухие факты без истерики.

  • Продукт уже сделан и заточен под Google: UX, офферы и воронка строились вокруг поискового трафика.

  • Аудитория живёт в Европе, доля Google по поиску там — доминирующая, Яндекс как основной источник трафика слабый и местами просто отсутствует.

  • Кабинет заблокирован, есть формальная возможность апелляции, но практика показывает: разбирательства могут тянуться неделями без гарантий результата.

  • Время и деньги, уже вложенные в продукт и рекламный сетап, — немалые, полный разворот в сторону Яндекса или другого канала = ещё месяцы работы и риск не выйти на сопоставимый объём трафика.

На этом этапе задача — увидеть реальность без «всё пропало» и «да нормально, сейчас разбанят».

Шаг 2. Красная шляпа: честно про эмоции

Здесь вообще не нужен рационал — только то, что ощущается.

  • Злость: «меня наказали без объяснения, хотя я не чувствую себя злодеем».

  • Страх: «если полезу в серяк — могу потерять вообще всё», «если уйду в Яндекс — просто похороню идею под Европу».

  • Усталость: «не хочу ещё месяц воевать с саппортом ради призрачного разбана».

Смысл — признать, какие решения ты принимаешь просто из страха или обиды, чтобы потом не маскировать это под «рациональный выбор».

Шаг 3. Чёрная шляпа: где можно умереть

Дальше — максимально пессимистичный взгляд на каждый сценарий.

  • Спорить с Google:

    • Потратишь недели на переписку, получая те же шаблонные ответы, без разбана.

    • За это время продукт не продвигается, выручка = 0, мотивация падает.

  • Купить новый кабинет у агентства:

    • Риск попасть под политику обхода системы и получить ещё более жёсткую блокировку.

    • Завязаться на стороннего посредника и их практики, которые могут завтра поломаться.

  • Прокси и серые схемы:

    • Бан по цепочке, блокировки платёжек, репутационные риски.

    • Постоянная гонка с системой вместо работы над продуктом.

  • Переписать продукт под Яндекс:

    • Месяцы разработки и адаптации ради канала, который изначально слаб для твоей ЦА.

    • Можно потратить ресурс и всё равно не выйти на нужный уровень трафика.

Чёрная шляпа нужна, чтобы честно увидеть, где ты можешь потерять больше, чем готов.

Шаг 4. Жёлтая шляпа: где тут шанс

Теперь тот же список, но с вопросом «что здесь может пойти хорошо?».

  • Спорить с Google:

    • Если разбанят — сохраняешь белую стратегию, легальный доступ к основному источнику трафика и не влезаешь в серые схемы.

  • Купить новый кабинет у агентства:

    • Быстрый возврат к тестам, если работать аккуратно и не нарушать политики.

    • Можно продолжить валидировать продукт и экономику уже сейчас, не замораживая проект на неопределённый срок.

  • Прокси / серяк:

    • Потенциально быстрый старт и доступ к объёмам там, где «всё перезабанено». Но цена этого старта слишком велика для соло‑инди.

  • Переписать продукт под Яндекс:

    • Диверсификация и снижение зависимости от одного монополиста.

    • Возможность протестировать рынки, где конкуренция ниже или трафик дешевле, если продукт адаптируем.

Жёлтая шляпа возвращает понимание, что в каждом сценарии есть не только «помереть», но и «выиграть» — вопрос цены и горизонта.

Шаг 5. Зелёная шляпа: альтернативы, о которых не думаешь в панике

Здесь цель — не выбирать между A/B/C, а придумать C1, C2, D.

Например:

  • Комбо‑стратегия: отправить официальную апелляцию в Google и параллельно запустить трафик через купленный у агентства кабинет с максимально белой конфигурацией.

  • Временный отход от жёсткой завязки на Ads: протестировать контент‑маркетинг, партнёрки или каталоги расширений, чтобы не быть полностью зависимым от одного канала.

  • Адаптация продукта под несколько рекламных сетей (включая Bing Ads или локальные решения), чтобы в будущем бан одного кабинета не ставил крест на всём проекте.

Зелёная шляпа — это место, где из «всё или ничего» появляется несколько ступеней и промежуточных экспериментов.

Шаг 6. Синяя шляпа: решение и правила игры

На этом этапе я собрал всё выше в конкретный план.

Что решил:

  • Не уходить в полностью серые схемы, где ставка — не только кабинет, но и платежи/аккаунты.

  • Зафиксировать стратегию:

    • подать нормальную апелляцию в Google (без иллюзий, но как обязательный шаг);

    • купить новый кабинет у агентства и использовать его максимально аккуратно, без нарушений политик и «серых» связок, чтобы продолжить тесты и не замораживать проект;

    • в параллель смотреть на альтернативные каналы, но не сносить архитектуру продукта ради гипотетического Яндекса под Европу.

Какие метрики для себя отметил:

  • стоимость клика и установки с нового кабинета;

  • конверсия в целевое действие внутри расширения;

  • стабильность аккаунта в течение первых недель работы.

Синяя шляпа — это момент, когда ты перестаёшь бесконечно «думать» и признаёшь: да, это не идеальное решение, но это проверяемый эксперимент с понятными правилами и горизонтом.

Как использовать это у себя

Если у тебя сейчас:

  • заблокировали рекламный кабинет;

  • умер основной источник трафика;

  • приходится выбирать между «серяком», паузой и сменой стратегии —
    вместо того, чтобы бесконечно крутить в голове одни и те же мысли, попробуй сделать так:

  1. Чётко сформулируй вопрос (одним предложением).

  2. Пройди по шляпам и честно выпиши по 3–5 пунктов на каждую.

  3. В синей шляпе зафиксируй: какое решение ты принимаешь сейчас, на какой срок, какие метрики покажут, что это было не зря.

Когда начал прогонять через шляпы не только монетизацию, но и такие аварийные ситуации, стало заметно, что во мне чаще всего орёт чёрная шляпа (паникёр) и иногда красная (обида/страх), а факты и выгоды просто не доходят до стола.

Если тебе заходит формат разборов решений инди‑разработчика (с цифрами, факапами и рабочими фреймворками), залетай в мой Telegram‑канал. Там чаще, короче и местами больнее

Показать полностью 1
0

Как Cursor помог переписать браузерное расширение за 2 часа: опыт миграции на единый стек

Последние пару недель занимаюсь унификацией технологического стека для всех своих pet-проектов и поделок. Цель — собрать единый тех-радар, чтобы не тратить время на переключение контекста между разными фреймворками и библиотеками.

Мой стек

Frontend:
- React (без сюрпризов)
- WXT (лучший фреймворк для браузерных расширений)
- MUI (библиотека UI-компонентов под Material Design)
- Netlify (бесплатный и надёжный хостинг)

Backend:
- Supabase (как Firebase, только лучше)
- Yandex Cloud (serverless-контейнеры + S3-хранилища)

Процесс

На выходных добрался до Speech to Text — браузерного расширения для транскрипции аудио. Оно было написано на vanilla JS ещё в первых версиях, и каждое обновление превращалось в квест по поиску багов и зависимостей.

С помощью Cursor (AI-ассистента для кода) переписал всё расширение за пару часов:

  • Перенёс на WXT (фреймворк для Chrome Extensions)

  • Заменил самописные компоненты на MUI

  • Добавил TypeScript для типобезопасности

  • Заодно запилил новую фичу: транскрипцию системного звука через Chrome Tab Capture API

Что получилось

Теперь Speech to Text может расшифровывать не только микрофон, но и всё, что играет на компьютере: YouTube-видео, Zoom-созвоны, лекции, подкасты и т.д.

Дополнительно добавил:

  • Аудиоплеер для предпросмотра файла перед отправкой

  • Анонимную расшифровку по прямой ссылке на аудио

Бонус

Модерация в Chrome Web Store прошла за 2 часа (обычно было 8-12). Предполагаю, что регулярные релизы дают "репутацию" у алгоритмов Google.

Выводы

Унификация стека — это не просто модное слово, а реальная экономия времени. Теперь могу быстро переключаться между проектами и переиспользовать компоненты без головной боли.

Хотите больше деталей?
Про процесс унификации стека, выбор инструментов и другие эксперименты с расширениями пишу в своём Telegram-канале @debug_leg. Там более неформальный формат: короткие посты, скриншоты процесса и честные истории про грабли. Подписывайтесь, если интересна кухня разработки.

Показать полностью 2
1

Диванная аналитика

Аналитика — один из ключевых инструментов в управлении современными цифровыми продуктами. Без данных о поведении пользователей невозможно понять, кто и как взаимодействует с вашим сайтом, приложением или сервисом, какие страницы работают эффективно, где пользователи теряются и почему падают конверсии. Аналитика помогает отслеживать рост, вовремя замечать проблемы, принимать решения на основе фактов и улучшать продукт так, чтобы он действительно работал лучше.

Однако всё чаще компании сталкиваются с тем, что популярные трекеры вроде Google Analytics или Яндекс.Метрики блокируются браузерами, adblock-расширениями или просто вызывают недоверие у пользователей. В условиях растущего запроса на приватность, прозрачность и независимость данных становится очевидной потребность в более простых, честных и контролируемых решениях.

Одно из таких решений — Umami Analytics.

Umami — это лёгкая, современная система веб-аналитики с открытым исходным кодом. Она не отправляет данные третьим лицам, не использует сторонние куки, работает быстро и предоставляет аккуратный минималистичный интерфейс. Среди ключевых возможностей: реал-тайм аналитика, отсутствие трекинга, который легко блокируется, и понятные метрики без перегруза.

Но здесь есть нюанс: официальный облачный сервис Umami стоит $20 в месяц. Для небольшого проекта, сайта или небольшого бизнеса это ощутимая сумма, особенно если нужна простая и приватная аналитика без обилия корпоративных функций.

И здесь появляется главный инсайт.

Все эти преимущества — real-time аналитика, приватность, удобный интерфейс, отсутствие блокировок — можно получить всего за 150 рублей в месяц, если развернуть Umami в режиме self-host. Более того, в этом случае вы получаете не только экономию, но и полный контроль над данными и инфраструктурой, что особенно важно в 2025 году.

В этом посте я покажу, как установить Umami на свой сервер, настроить её за несколько минут и получить функциональность уровня платных SaaS-решений — за минимальные деньги и без компромиссов по приватности.

Как развернуть Umami за 150 рублей в месяц

Этот пост является текстовой версией видео: https://www.youtube.com/watch?v=u7WBRaX8i9U

Шаг 1. Удалённый сервер (VPS)

У Cloud.ru есть отличная возможность получить слабенькую, но очень выносливую виртуальную машину в бессрочное бесплатное пользование. Платить нужно только за публичный IP-адрес — а это как раз около 150 рублей в месяц.

1.1 Регистрируемся на Cloud.ru

Переходим на сайт Cloud.ru и создаём аккаунт. Потребуется номер телефона для подтверждения.

1.2 Пополняем баланс (минимум 200 ₽)

Это нужно для того, чтобы сразу оплатить публичный IP и избежать блокировки ресурсов.

1.3 Открываем страницу тарифа Free Tier

Переходим по ссылке:

https://cloud.ru/products/evolution-compute

Листаем вниз до раздела Free tier.

1.4 Создаём виртуальную машину

Вариант Free Tier нельзя настраивать по ресурсам, но можно выбрать способ аутентификации.

Рекомендую метод SSH-ключ — он безопаснее и удобнее, чем пароль.

1.5 Запускаем виртуалку

Нажимаем кнопку Создать и ждём, пока виртуальная машина перейдёт в статус «Running».

ВАЖНО После создания обязательно подключите публичный IP-адрес, иначе вы не сможете зайти на сервер по SSH или открыть веб-интерфейс Umami.

Шаг 2. Настройка удалённого сервера

Я использовал виртуалку на Ubuntu 24.04, поэтому команды ниже рассчитаны именно на неё. Umami и PostgreSQL мы будем запускать в Docker через Docker Compose.

Если вы используете другую ОС — часть команд может отличаться. В этом случае можно либо адаптировать шаги вручную, либо попросить любую LLM помочь под вашу систему.

2.1 Обновляем систему

sudo apt update

sudo apt upgrade -y

2.2 Удаляем старые версии Docker (на всякий случай)

sudo apt remove docker docker-engine docker.io containerd runc

2.3 Устанавливаем необходимые зависимости

sudo apt install -y ca-certificates curl gnupg

2.4 Добавляем официальный GPG-ключ Docker

sudo install -m 0755 -d /etc/apt/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

sudo chmod a+r /etc/apt/keyrings/docker.gpg

2.5 Добавляем Docker Repository

echo \

"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \

https://download.docker.com/linux/ubuntu \

$(. /etc/os-release && echo $VERSION_CODENAME) stable" | \

sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

2.6 Устанавливаем Docker Engine и Docker Compose Plugin

sudo apt update

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

2.7 Разрешаем запуск Docker без sudo

sudo usermod -aG docker $USER

newgrp docker

2.8 Проверяем установку Docker

docker --version

docker run hello-world

Если вывод показывает версию Docker и затем приветственное сообщение "Hello from Docker!" — значит, всё установлено успешно и сервер готов к разворачиванию Umami.

Шаг 3. Запускаем Umami

Теперь, когда Docker установлен, можно развернуть Umami и PostgreSQL с помощью Docker Compose. Конфигурация максимально простая — всё поднимается в два контейнера.

3.1 Создаём Docker Compose файл

Создаём каталог и открываем файл:

mkdir umami && cd umami

nano docker-compose.yml

Вставляем конфигурацию: https://gist.github.com/eryabyshev/ea25faa285820d0856a1e1c2a7edb8e3

⚠️ ВАЖНО!

Обязательно замените:

umami_password на ваш реальный пароль для БД,

your-random-hash на случайную строку (можно сгенерировать командой openssl rand -hex 32).

3.2 Поднимаем контейнеры

Выполняем:

docker compose up -d

Проверяем статус:

docker ps

Должны появиться два контейнера: umami и umami_postgres.

3.3 Пробрасываем порт 3000 в Cloud.ru

Чтобы открыть web-интерфейс Umami, нужно разрешить входящие запросы на порт 3000.

Переходим в раздел Группы безопасности: https://console.cloud.ru/spa/svp/security-groups

Находим строку, где интерфейс подключён (ДА).

Открываем вкладку Правила.

Добавляем новое правило:

Тип: Входящее

Протокол: TCP

Порт: 3000

Источник: 0.0.0.0/0 (если хотите открыть для всех)

3.4 Открываем Umami в браузере

Берём публичный IP вашей виртуальной машины и открываем:

http://<public_ip>:3000

Должна появиться панель авторизации Umami.

Логин по умолчанию: admin

Пароль по умолчанию: umami

Сразу после входа обязательно поменяйте пароль администратора.

Шаг 4. Подключаем Umami к веб-странице

После того как Umami запустилась и вы можете открыть панель по адресу http://<public_ip>:3000, можно приступить к интеграции трекинга на сайт.

4.1 Первый вход

Используем стандартные данные:

Логин: admin

Пароль: umami

После входа сразу меняем пароль на свой.

4.2 Переходим в раздел Websites

В левом меню выбираем Websites.

4.3 Добавляем новый сайт

Нажимаем кнопку Add website, заполняем название и сохраняем.

После создания появится блок настроек сайта — открываем его.

4.4 Копируем скрипт трекера

В настройках сайта есть готовый <script> — копируем его, он будет выглядеть примерно так:

<script defer src="http://<public_ip>:3000/script.js" data-website-id="ВАШ_ID"></script>

4.5 Используем HTML-песочницу для проверки

Чтобы убедиться, что всё работает, создадим простую локальную HTML-страницу.

Замените:

<public_ip> — на публичный IP вашей виртуалки

CODE — на ID сайта из Umami

<!DOCTYPE html>

<html lang="ru">

<head>

<meta charset="UTF-8" />

<title>Пример страницы с Umami</title>

<!-- Umami tracking -->

<script defer src="http://<public_ip>:3000/script.js" data-website-id="CODE"></script>

</head>

<body>

<h1>Test Umami</h1>

<button id="buyBtn">Купить</button>

<script>

const btn = document.getElementById("buyBtn");

btn.addEventListener("click", () => {

if (window.umami && typeof window.umami.track === "function") {

window.umami.track("click_buy_button"); // имя события

console.log("Umami event sent");

} else {

console.warn("Umami object not ready yet", window.umami);

}

});

</script>

</body>

</html>

Сохраните файл и просто откройте его в браузере — локально, без загрузки на сервер.

4.6 Проверяем посещения

Теперь перезагрузите страницу — в интерфейсе Umami во вкладке Realtime появится ваш визит.

4.7 Проверяем события

Нажмите кнопку Купить.

События будут отображаться во вкладке Events для вашего сайта:

там появится событие click_buy_button.

Заключение

Развернуть собственную систему аналитики — проще, чем кажется. Всего за 150 рублей в месяц вы получаете функциональность уровня платных сервисов, полный контроль над данными, приватность, real-time метрики и защиту от блокировок. Umami отлично подходит для небольших проектов, pet-приложений, лендингов и любых сервисов, где нужна честная статистика без лишних зависимостей.

Если вы раньше не поднимали аналитику самостоятельно — этот гайд показывает, что всё решается за 10–15 минут. Дальше вы сможете добавлять события, подключать несколько сайтов, настраивать аналитику под свои задачи и развивать инфраструктуру так, как вам удобно.

Полная документация Umami:

👉 https://umami.is/docs

У меня есть Telegram-канал, где я делюсь опытом запуска инди-проектов, рассказываю о своих экспериментах и публикую практичные гайды:

👉 https://t.me/debug_leg

Если статья была полезной — поддержите её лайком или репостом. Это помогает делать больше практичного контента ❤️

Показать полностью 3 1
1

Мой стек для запуска MVP

Мой стек для запуска MVP

После отпуска я понял простую вещь - двух недель достаточно, чтобы забыть вообще всё, чем ты занимался.
Если у тебя нет структуры, стек превращается в хаос из случайных библиотек, фреймворков и зависимостей.

Поэтому я сел и собрал для себя техрадар - единый стек, который позволяет запускать pet-проекты и мини SaaS быстро и без боли.


⚙️ Frontend

React
🧠 Почему: куча библиотек, море документации и огромное комьюнити. Плюс масса готовых компонентов - не надо изобретать велосипед.

WXT
⚡ Почему: лучший фреймворк для браузерных расширений, если нужно быстро. Реально сокращает путь от идеи до первой установки

MUI
🎨 Почему: так как большинство моих проектов - Chrome Extensions, UI-компоненты под Material Design органично вписываются в браузер от Google.

Netlify
☁️ Почему: одна из самых удобных платформ для веб-разработки. Автоматическая сборка, тестирование и деплой в пару кликов. Работает стабильно и без боли.


🧩 Backend

Supabase
🗄 Почему: open-source альтернатива Firebase, но с Postgres под капотом — понятным, гибким и предсказуемым. Есть всё: авторизация, база, edge-функции и SQL-запросы.

Yandex Cloud
💾 Почему: недорогой S3, с "льготным" объёмом данных, за который не берут денег. Плюс умеет поднимать Docker-контейнеры в serverless-режиме. Идеально для пет-проектов.


🧱 Инфраструктура

CI/CD — Jenkins
🔁 Почему: не прожорлив, стабилен и с кучей плагинов. Работает даже на обычном VPS.

GlitchTip
🐞 Почему: не ест столько памяти, как Sentry, но совместим с его API и библиотеками. Отличный вариант для отслеживания ошибок.

Umami
📊 Почему: не блокируется ad-блоками, лёгкая и быстрая. Отличная альтернатива Google Analytics и Яндекс.Метрике.


🧰 Инструменты

JetBrains IDEA
💻 Почему: всю жизнь писал на Java и Kotlin - это мой родной IDE. Самый знакомый и надёжный инструмент.

WebStorm
🧠 Почему: по сути та же IDEA, только заточенная под JS и TypeScript.

Cursor
🚀 Почему: ускоряет разработку. Во второй версии можно подключить debug port Chromium и буквально «вайбкодить» с ИИ в реальном времени.

DBeaver
📘 Почему: купить лицензию DataGrip сложно, а DBeaver - почти то же самое. Не идеально, но достаточно для работы с БД.

GitHub
🌐 Почему: так исторически сложилось. Репозиторий, автодеплой, CI - всё в одном месте.


💬 Языки

TypeScript
🧩 Почему: я привык к типизированной Java, и JS без типов меня бесит 😅.
Плюс Cursor тратит меньше токенов, потому что не нужно проверять типы, и упрощается процесс vibe debugging - сразу понятно, что за данные под капотом.

Python
🐍 Почему: стараюсь минимизировать, но иногда выручает. Особенно когда дело доходит до ML и AI - ребята из этой среды его обожают.

(А вот Kotlin, как бы я его ни любил, сюда просто не ложится.)


Сейчас думаю над системой логов и метрик — скорее всего, выберу VictoriaMetrics.


Ещё у меня есть телеграм-канал, где я рассказываю, как всё это использую вживую, и делюсь процессом разработки своих пет-продуктов 👉 t.me/debug_leg

Показать полностью

Как понять, полетит ли твой пет-проект, ещё до того как ты его закодил

Как понять, полетит ли твой пет-проект, ещё до того как ты его закодил

Когда я впервые решил попробовать себя на маркетплейсах, первое, что сделал — посчитал математику.
Какие товары выгодно продавать, а какие не имеет смысла даже закупать.
С этого момента я понял одну простую вещь: экономика всегда важнее идеи.

С IT-проектами, мини-SaaS и прочими пет-поделками всё работает точно так же.
Некоторые идеи звучат круто, но экономика там минусовая ещё до релиза.
А какие-то — наоборот, простые, скучные, но с отличной маржинальностью.

Чтобы не тратить время на «мертвые» идеи, я собрал простой калькулятор экономики пет-проекта.
Он помогает понять, сколько денег нужно вложить и сколько можно заработать за первые три месяца, если запускаться через поисковый трафик.

Внутри — всё по делу: трафик, конверсии, CTR, CPC, расходы, цена подписки.
В итоге калькулятор покажет, во что ты реально влезешь, и стоит ли вообще кодить идею или лучше оставить её в «папке с концептами».

🧮 Калькулятор можно посмотреть и попробовать тут:
👉 Google Sheets — Экономика пет-проекта

Я сделал его под свои запуски, но он подойдёт любому, кто хочет тестировать идеи быстро и с холодной головой.

Показать полностью 1
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества