← все кейсы · self-hosted AI-платформа

Своя инфраструктура для open-source AI-ассистента.

Клиент — AI-стартап в области носимых устройств — хотел уйти от облака основного проекта Omi и развернуть всё на своём VPS: бэкенд, базу, ключи к LLM и STT. Полная независимость от внешней инфраструктуры. От первого коммита до APK и iOS-сборки — 14 дней.

срок · 14 дней стек · Python · Firebase · Deepgram в проде

01 · Контекст и задача

Клиент работает с open-source AI-платформой Omi (github.com/BasedHardware/omi) — это голосовой ассистент с подключением к носимому устройству: микрофон записывает разговоры, бэкенд транскрибирует через STT, LLM делает краткое содержание и собирает Knowledge Graph пользователя.

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

Что просил клиент: развернуть полностью собственный экземпляр платформы — на своём VPS, со своим Firebase, со своими ключами к LLM и STT. Чтобы запустить Android APK и iOS-сборку, которые ходят строго к этому бэкенду. Бюджет — 14 дней.

02 · Что было сложно

  • Кодовая база не рассчитана на self-hosted. Omi из коробки запускается под ngrok + чужие облачные сервисы. Нет docker-compose, нет инструкции к деплою, нет конфига под прод. Всё это нужно было собрать с нуля поверх чужого кода.
  • Жёсткие зависимости от Pinecone, Redis (Upstash), Typesense. Эти сервисы используются в Omi на уровне импортов и инициализации. Даже если функционально клиенту они не нужны — без них бэкенд просто не стартует. Каждый из них — отдельное решение: либо заглушка, либо минимальный локальный инстанс, либо self-hosted альтернатива.
  • STT и LLM — отдельные подрядчики. Deepgram (Speech-to-Text) и OpenRouter (прокси к OpenAI) — разные API с разными лимитами и форматами ошибок. Их нужно было подключить так, чтобы при превышении лимита одного из них всё приложение не валилось.
  • Две сборки в одном договоре. Android APK и iOS — это разные пайплайны: Gradle vs Xcode, разные подписи, разные требования. iOS дополнительно требовал Apple Developer аккаунт клиента с настройкой провижн-профилей.
  • Передача в поддержку. Клиент — стартап, у них нет DevOps. Документация должна быть такой, чтобы оператор-неразработчик мог перезапустить контейнер, обновить ключ, посмотреть логи — без обращения к нам.

Open-source ≠ готовое решение. «Просто разверни» — это первая ловушка любого подобного проекта.

03 · Решения

Адаптация чужого кода без форка

Мы не форкали Omi и не правили исходники. Все настройки self-hosted режима вынесли в .env: API_BASE_URL, ключи Firebase, эндпоинты STT/LLM, переключатели заглушек для Pinecone/Typesense. Когда основной проект обновится — клиент может подтянуть свежий код, не теряя свои настройки.

Жёсткие зависимости от облачных сервисов закрыли минимальными способами: Pinecone заменили на in-memory заглушку с тем же интерфейсом (клиенту векторный поиск не нужен), Redis подняли локальный в Docker, Typesense обошли — функции, которые его используют, отключаются флагом.

Инфраструктура в Docker Compose

Бэкенд, Nginx и Redis — отдельные сервисы в одном compose-файле. Compose описывает не только запуск, но и зависимости (Nginx не стартует, пока backend не отвечает на healthcheck), и автозапуск при ребуте VPS (restart: unless-stopped). Один файл — весь стейт инфры.

Экран онбординга: How did you find us
Один из экранов онбординга в собранном APK, который ходит к нашему self-hosted бэкенду

SSL через certbot, без ручных продлений

Let's Encrypt подключили через отдельный certbot-контейнер. Он раз в 12 часов проверяет срок действия и сам выпускает новые сертификаты. Nginx раз в 6 часов перезагружает конфиг — чтобы свежие cert'ы подхватились без даунтайма. Клиенту больше не нужно держать в календаре «продлить SSL».

Firebase как «бесплатное» хранилище

Auth (email/пароль), Firestore (пользовательские данные) и Storage (аудиозаписи) — это всё Firebase Blaze клиента. Мы только настроили проект, подключили сервис-аккаунт в бэкенд, разнесли коллекции, написали правила безопасности. Никакой собственной БД клиенту держать не пришлось.

Два STT/LLM-провайдера

Deepgram — STT с самым низким latency для русского и английского. OpenRouter — прокси к OpenAI и десяткам других LLM с возможностью переключения провайдера через конфиг, без релизов. Ключ к OpenAI можно поменять на ключ к Anthropic за минуту — клиент остаётся гибким.

Документация под не-разработчика

Финальный документ — это не README.md для гитхаба, а пошаговая инструкция эксплуатации. Где какие ключи, как перезапустить, что делать если кончается место, как обновить URL бэкенда в APK. Размер — 13 разделов, всё через простые ssh и docker compose команды.

04 · Результат

Срок 14 днейот ТЗ до прод-сборки
Платформы 2Android APK + iOS
Интеграции 5Firebase · Deepgram · OpenRouter · Nginx · Docker

Клиент получил полностью независимый от облака Omi экземпляр платформы на своём VPS (Ubuntu 24.04, 2 vCPU, 4 GB RAM). Бэкенд работает в проде, отдаёт API мобильному приложению, общается с Firebase, тратит токены OpenRouter и Deepgram по ключам клиента.

Сборка Android APK (130 МБ, flavor prod) ставится на устройство через стандартную установку из неизвестных источников. iOS-сборка ушла в TestFlight для внутреннего тестирования команды клиента.

Самое важное — это контроль. Все аудиозаписи и транскрипты пользователей теперь хранятся в Firestore клиента, не у третьих лиц. Ключи к LLM — у клиента. VPS — у клиента. Никаких блокировок и тарифных сюрпризов от основного проекта.

05 · Что дальше

Проект на поддержке. Основные следующие задачи — расширение функционала (включение голосового онбординга и Knowledge Graph, которые пока скрыты флагом), обновление под новые модели в OpenRouter, и публикация в RuStore / App Store.

Платформа Omi обновляется в основном репозитории — мы будем подтягивать апдейты и адаптировать под self-hosted конфигурацию клиента, без ломки прода.

Похожий проект

У вас тоже open-source AI-проект, который надо посадить на свою инфру?

Self-hosted деплой чужой кодовой базы — частая задача у стартапов в AI. В первом письме пришлите ссылку на репозиторий и опишите, что хотите оставить от облака, а что — забрать к себе. Пришлём разбор и оценку в течение 24 часов.