- Инженерный блог о self-hosted инфраструктуре/
- Статьи/
- Суверенная операционка без Битрикса: AI-ready стек на одном сервере/
Суверенная операционка без Битрикса: AI-ready стек на одном сервере

Содержание
Суверенная операционка без Битрикса: AI-ready стек на одном сервере #
Один сервер. Один сисадмин. Полный контроль над данными и готовность к эре AI. Разбор архитектуры для компаний, которые устали от SaaS-зависимостей и хотят нормальную операционку.
Давайте честно: бухгалтерия — святое, а всё остальное — архитектурный кринж #
Сразу расставим точки над «i». 1С:Бухгалтерия — это монополия, и это нормально. Она зашита в ДНК российского налогового кодекса. Пытаться заменить её на Open Source в SMB-компании — это мазохизм. Обычно в малом и среднем бизнесе бухгалтерия вообще на аутсорсе: они работают в своей 1С/СБИС, и это правильно.
Мы сюда не за этим. Мы сюда за тем, чтобы построить операционку компании: управление задачами, база знаний, учёт активов, регламенты, онбординг, юридические шаблоны. И вот тут начинается архитектурный ужас.
Вариантов обычно два(не считая более узких SaaS), и оба плохие:
- Битрикс24 — SaaS-комбайн, где при блокировке аккаунта, уходе из облака или просто изменении тарифа компания теряет всю корпоративную память. Плюс вендор-лок: никуда не уедешь с их данными без слёз.
- 1С:Предприятие для операционки (Документооборот, Задачи) — фреймворк для бэкофиса, натянутый на веб-интерфейс уровня 2005 года. Любой чих — звонок франчайзи и почасовая оплата.
А теперь вопрос: что если вместо этого за 3 года вы потратите ~105 тысяч рублей + один компьютер, получите полный контроль над данными и бонусом — AI-ready стек, который умеет отвечать на вопросы сотрудников по вашей же внутренней документации?
Философия: Суверенная операционка #
Парадигма та же, что и в моей первой статье про K3s-кластер: моё железо, мои правила, мои модели.
Для SMB-компании это значит:
- Layer 1-2: свой сервер в офисе или арендованный в ДЦ, не виртуалка провайдера
- Layer 3-4: свой DNS (Unbound), свой firewall, своя сеть
- Layer 7: свои сервисы вместо SaaS-подписок
- AI Layer: локальная LLM + RAG по документам компании, без отправки данных в OpenAI/Anthropic/Alibaba/Deepseek
Важный нюанс: вся обвязка — открытая и интегрируемая. У каждого сервиса есть REST API или вебхуки. Если вдруг понадобится связать таск-трекер с 1С бухгалтера для автогенерации счетов — это делается за вечер, а не через интегратора за 50к.
Ключевое отличие от первой статьи: здесь не нужен Kubernetes. Один сервер, Docker Compose (или Podman), и всё. Сисадмин средней руки справится.
Архитектура: один сервер, шесть сервисов #
Reverse Proxy + TLS"] Unbound["Unbound :53
Recursive DNS"] AdGuard["AdGuard Home
DNS Filtering"] end subgraph Apps["Application Layer"] Kaneo["Kaneo
Task Management"] Wiki["Wiki.js
Knowledge Base"] SnipeIT["Snipe-IT
Asset Management"] end subgraph Auth["Auth Layer"] Keycloak["Keycloak
SSO / OIDC"] end subgraph Data["Data Layer"] PG["PostgreSQL 16
Shared DB"] VK["Valkey 8
Cache/Sessions"] Qdrant["Qdrant
Vector DB"] end subgraph AI["AI Layer"] Ollama["Ollama
Local LLM"] end end Client["Сотрудники / Клиенты"] --> Traefik Traefik --> Apps Traefik --> Keycloak Apps --> Auth Apps --> Data Keycloak --> Data Wiki --> AI AI --> Qdrant AdGuard --> Unbound style Server fill:#f0f9ff,stroke:#2563eb,stroke-width:2px style Edge fill:#fef3c7,stroke:#d97706 style Apps fill:#dcfce7,stroke:#16a34a style Auth fill:#fee2e2,stroke:#dc2626 style Data fill:#e0e7ff,stroke:#4f46e5 style AI fill:#fae8ff,stroke:#a855f7
Почему именно эти сервисы и что они заменяют в популярном SaaS:
| Роль | Сервис | Зачем | Альтернатива в Битрикс24 |
|---|---|---|---|
| Управление задачами | Kaneo | Современный Kanban, MIT-лицензия | «Задачи и проекты» |
| База знаний | Wiki.js | Markdown, поиск, OIDC-авторизация | «База знаний» |
| Учёт активов | Snipe-IT | Железо, лицензии, расходники | Отсутствует (или через CRM-кастомизацию) |
| Единый вход | Keycloak | SSO во все сервисы | Внутренняя авторизация Битрикс24 |
| Приватный DNS | Unbound | Рекурсор без телеметрии | — |
| Сетевой ad-block | AdGuard Home | Блокировка трекеров на уровне сети | — |
Бонус — AI-ready слой, которого в принципе нет у вендоров:
| Компонент | Зачем |
|---|---|
| Ollama | Локальная LLM (Llama 3.1, Qwen, DeepSeek) |
| Qdrant | Векторная БД для эмбеддингов документов |
| Wiki.js + RAG | Поиск по базе знаний компании через LLM |
Docker Compose: рабочий скелет #
Файл docker-compose.yml, который можно скопировать и запустить:
version: '3.8'
networks:
office:
driver: bridge
volumes:
postgres_data:
valkey_data:
keycloak_data:
wiki_data:
snipeit_data:
kaneo_data:
qdrant_data:
ollama_data:
services:
# === REVERSE PROXY ===
traefik:
image: traefik:v3.7
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=ssl@company.local"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
restart: unless-stopped
# === SHARED DATABASES ===
postgres:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh
restart: unless-stopped
valkey:
image: valkey/valkey:8-alpine
volumes:
- valkey_data:/data
restart: unless-stopped
# === SSO ===
keycloak:
image: quay.io/keycloak/keycloak:25.0
command: start
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_USERNAME: postgres
KC_DB_PASSWORD: ${DB_PASSWORD}
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
KC_HOSTNAME: sso.company.local
KC_PROXY_HEADERS: xforwarded
KC_HTTP_ENABLED: "true"
labels:
- "traefik.enable=true"
- "traefik.http.routers.keycloak.rule=Host(`sso.company.local`)"
- "traefik.http.routers.keycloak.entrypoints=websecure"
- "traefik.http.routers.keycloak.tls.certresolver=letsencrypt"
depends_on: [postgres]
restart: unless-stopped
# === WIKI ===
wiki:
image: requarks/wiki:2
environment:
DB_TYPE: postgres
DB_HOST: postgres
DB_PORT: 5432
DB_NAME: wiki
DB_USER: postgres
DB_PASS: ${DB_PASSWORD}
labels:
- "traefik.enable=true"
- "traefik.http.routers.wiki.rule=Host(`wiki.company.local`)"
- "traefik.http.routers.wiki.entrypoints=websecure"
- "traefik.http.routers.wiki.tls.certresolver=letsencrypt"
depends_on: [postgres]
restart: unless-stopped
# === ASSET MANAGEMENT ===
snipeit:
image: snipe/snipe-it
environment:
DB_CONNECTION: pgsql
DB_HOST: postgres
DB_DATABASE: snipeit
DB_USERNAME: postgres
DB_PASSWORD: ${DB_PASSWORD}
APP_URL: https://assets.company.local
labels:
- "traefik.enable=true"
- "traefik.http.routers.snipeit.rule=Host(`assets.company.local`)"
- "traefik.http.routers.snipeit.entrypoints=websecure"
- "traefik.http.routers.snipeit.tls.certresolver=letsencrypt"
volumes:
- snipeit_data:/var/lib/snipeit
depends_on: [postgres]
restart: unless-stopped
# === TASKS ===
kaneo:
image: ghcr.io/usekaneo/api:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.kaneo.rule=Host(`tasks.company.local`)"
- "traefik.http.routers.kaneo.entrypoints=websecure"
- "traefik.http.routers.kaneo.tls.certresolver=letsencrypt"
volumes:
- kaneo_data:/app/data
restart: unless-stopped
# === DNS ===
unbound:
image: mvance/unbound:latest
ports:
- "53:53/tcp"
- "53:53/udp"
volumes:
- ./unbound/unbound.conf:/opt/unbound/etc/unbound/unbound.conf:ro
restart: unless-stopped
# === AD BLOCK ===
adguard:
image: adguard/adguardhome
ports:
- "3000:3000/tcp"
volumes:
- ./adguard/work:/opt/adguardhome/work
- ./adguard/conf:/opt/adguardhome/conf
restart: unless-stopped
# === AI LAYER ===
ollama:
image: ollama/ollama
volumes:
- ollama_data:/root/.ollama
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
restart: unless-stopped
qdrant:
image: qdrant/qdrant
volumes:
- qdrant_data:/qdrant/storage
restart: unless-stopped
И init-db.sh для создания баз:
#!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
CREATE DATABASE keycloak;
CREATE DATABASE wiki;
CREATE DATABASE snipeit;
CREATE DATABASE kaneo;
EOSQL
AI-ready слой: как это работает #
Вот где наш стек реально выигрывает у любого SaaS.
Как это работает:
- Wiki.js экспортирует все страницы в Markdown
- Скрипт чанкает документы (по 512 токенов) и считает эмбеддинги через
nomic-embed-text - Эмбеддинги складываются в Qdrant
- При вопросе — similarity search по векторам, контекст идёт в LLM
- LLM отвечает на основе ваших документов, а не галлюцинирует из интернета
Что это даёт компании (именно операционке, а не бухгалтерии):
- Юристы спрашивают про регламенты → получают ответ со ссылкой на пункт типового договора
- Сейлзы спрашивают про скрипты и ценообразование → получают ответ из внутреннего playbook’а
- HR и новички онбордятся в 3 раза быстрее: “как оформить пропуск”, “где взять VPN”, “как согласовать отпуск”
- Менеджеры получают выжимки из регламентов без чтения 50-страничных PDF
- Никакие данные не покидают периметр компании
Бухгалтерия в этом не участвует — у них своя 1С, свои регламенты и свои риски. Не смешиваем.
Стоимость: одна RTX 3060 12GB (~25к ₽) позволяет гонять Llama 3.1 8B с скоростью 20-30 токенов/сек. Для компании из 20 человек этого достаточно.
Математика выгоды: Self-hosted vs Битрикс24 (3 года) #
Бухгалтерию из сравнения убираем — она вне конкуренции и живет своей жизнью на аутсорсе. Сравниваем операционку: наш стек против типичного сетапа на Битрикс24 с модулями для команды из 20 человек.
Затраты на Битрикс24 для 20 человек (3 года):
- Тариф «Профессиональный» (нужен для базы знаний и CRM): ~4 849 ₽/мес × 36 = ~175к ₽
- Дополнительные модули (Задачи+, Расширенная база знаний): ~60к ₽
- Внедрение/кастомизация от партнёра: от 80к ₽
- ИТОГО: ~315к ₽ минимум
- И вы остаётесь в SaaS-зависимости с закрытым кодом и невозможностью локальной LLM
Затраты на self-hosted стек (3 года):
- Сервер (Dell R740 б/у или мини-ПК): 60-80к ₽
- GPU для LLM (RTX 3060): 25-40к ₽
- Электричество (300 Вт × 3 года): ~20-25к ₽
- Домен + SSL: 2000 ₽ (Let’s Encrypt)
- ИТОГО: ~107к ₽
Экономия: ~208к ₽ за 3 года + бонусом получаете AI-ready инфраструктуру и полный контроль над данными, чего у SaaS нет в принципе.
Подводные камни #
Я не буду делать вид, что это просто. Вот реальные грабли:
1. Keycloak — Java-монстр #
Keycloak жрёт 512MB–1GB RAM просто за факт существования. Для компании из 20 человек это overkill.(Хотя для параноиков-самое то.)
Решение: рассмотреть Authentik (Python, легче в 3 раза) или Dex (OIDC-провайдер, почти не ест). Если у вас меньше 10 пользователей — Keycloak не нужен вообще, хватит базовой авторизации в каждом сервисе.
2. Бэкапы volumes #
Если не настроить бэкап /var/lib/docker/volumes — потеряете всё при смерти диска.
Решение: borgmatic + ежедневные бэкапы на внешний MinIO/S3. Стратегия 3-2-1: 3 копии, 2 разных носителя, 1 копия оффсайт.
3. Watchtower — зло для продакшена #
Многие ставят watchtower для автообновления образов. Это риск: образ может сломать совместимость.
Решение: cron + ручные обновления раз в месяц после чтения changelog’ов.
4. Unbound vs AdGuard Home #
Это не конкурирующие, а взаимодополняющие сервисы. AdGuard Home — DNS-форвардер с фильтрами, Unbound — полноценный рекурсор.
Правильная схема: клиенты → AdGuard Home (фильтрация) → Unbound (рекурсия) → root DNS.
5. PostgreSQL на всех — это риск #
Все сервисы в одной инстансе Postgres — удобно, но один падающий запрос может повлиять на всех.
Для продакшена: отдельные инстансы Postgres для критичных сервисов (Snipe-IT отдельно, Keycloak отдельно).
Docker vs Podman: что выбрать #
Для этой статьи я использовал Docker Compose — он знаком большинству сисадминов. Но есть альтернатива: Podman.
Почему Podman может быть лучше:
- Rootless-контейнеры (сисадмин параноит — правильно делает)
- Нет демона (нет единой точки отказа)
- Drop-in замена:
podman-compose up -dработает с тем жеdocker-compose.yml
Почему Docker может быть лучше:
- Больше документации
docker-compose watchдля live-reload при разработке- Привычнее для тех, кто пришёл из облаков
Для компании из 20 человек разницы почти нет. Выбирайте то, что знает ваш сисадмин.
План внедрения для сисадмина #
- День 1: Арендовать/купить сервер (16GB RAM минимум, 24GB если будет LLM)
- День 2: Debian 12 + Docker + Traefik, базовая настройка firewall
- День 3-5: Развернуть базовый стек (Postgres, Keycloak, Wiki.js)
- День 6-7: Настроить SSO, завести пользователей
- Неделя 2: Подключить Kaneo и Snipe-IT, перенести данные из Excel
- Неделя 3: Настроить Unbound + AdGuard Home, перевести клиентов
- Неделя 4: Настроить бэкапы через borgmatic
- Месяц 2: Внедрить AI-слой (Ollama + Qdrant + RAG)
- Постоянно: Документировать всё в Wiki.js (мета-уровень)
Заключение #
В 2026 году SaaS-монополии — не единственная опция для операционки SMB-компаний. Self-hosted стек на опенсорсе даёт:
- Экономию ~210к ₽ за 3 года по сравнению с Битрикс24
- Полный контроль над данными (никаких SaaS-вендоров)
- AI-ready инфраструктуру, которой нет ни у одного коробочного решения
- Бухгалтерия при этом спокойно работает в своей 1С на аутсорсе — без конфликтов и миграций
Цена — один сервер и один толковый сисадмин. Если у вашей компании есть и то, и другое — вы уже готовы.
Если интересно посмотреть на реальные конфиги Unbound, скрипт индексации Wiki.js в Qdrant, или обсудить архитектуру под ваш размер компании — залетайте в Telegram-канал. Там выложу ссылки на репозиторий с готовыми docker-compose и Ansible-плейбуками.
📬 Связаться со мной
Если у вас есть вопросы по инфраструктуре, предложения по сотрудничеству или просто хотите обсудить DevOps — пишите в Telegram.
Отвечаю в течение 24–48 часов. По консультационным вопросам — сразу с описанием задачи.