Поставка софта Модели поставки: коробка, SaaS, self-hosted, гибрид
0%

Модели поставки: коробка, SaaS, self-hosted, гибрид

Модели поставки: коробка, SaaS, self-hosted, гибрид

Команда из шести человек сделала анализатор логов. Два года продавали архив: клиент скачивал .tar.gz, ставил на свой сервер, платил один раз и жил. К концу второго года — 34 клиента и 11 разных версий в проде, самая старая младше актуальной на полтора года; каждый баг-репорт начинался с «а какая у вас версия и на чём вы её запустили», и половина времени двух инженеров уходила на воспроизведение чужой среды.

Они переехали в SaaS. Через полгода версия стала одна, воспроизведение — тривиальным, выручка — предсказуемой. Заодно появилось круглосуточное дежурство, счёт за облако размером с зарплату инженера, чужие персональные данные в своей базе и два ушедших клиента из банковского сектора: их служба безопасности не выпускает логи наружу. Ни одно решение не было ошибкой — просто у каждой модели была цена, и оба раза её узнали задним числом. Модель поставки не маркетинговая наклейка, а инженерное решение: сколько будет живых версий, кого разбудят ночью, где лежат данные клиента и что вы обязаны сделать, если завтра закроетесь. Карта трека — в главе Поставка софта: карта трека.

Модель поставки — это ответ на три вопроса

Все существующие модели — комбинации ответов на три вопроса. Не «SaaS или не SaaS», а: где выполняется код (у вас, у клиента или на устройстве пользователя); кто решает, когда ставить новую версию (вы выкатываете, когда готовы, — или клиент обновляется, когда захочет, и вы не контролируете, что сейчас работает у людей); кто платит за простой — не «кто виноват», а у кого горит прямо сейчас: ваш дежурный инженер или админ клиента.

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

Ось Что измеряем Почему это инженерный вопрос
Число живых сборок Версии × платформы × архитектуры, которые вы обязаны чинить Растёт произведением, а не суммой
Стоимость исправления Часы от «нашли баг» до «у всех работает» В коробке — месяцы, в SaaS — часы
Стоимость обслуживания Инфраструктура и поддержка на клиента в месяц Определяет, при какой цене вы в плюсе
Владение данными У кого лежат данные и кто отвечает за утечку Тянет юрисдикции и требования регуляторов
Обязательства на выходе Что вы должны, если продукт закрывается Мигрировать, отдать данные, отдать исходники

Матрица ответственности: кто отвечает за какой слой в четырёх моделях поставки

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

Коробка: артефакт, который живёт без вас

«Коробка» — любая поставка готового артефакта, который дальше живёт своей жизнью: установщик для десктопа, .deb или .rpm, образ прошивки, приложение из магазина, архив с шаблонами. Физической коробки давно нет, модель осталась той же: единовременная передача экземпляра плюс, возможно, право на обновления. Покупателю это даёт независимость от вашей судьбы — купленная версия продолжит работать, если вы поднимете цену, закроете тариф или разоритесь; предсказуемый разовый расход вместо счёта, который растёт сам; работу без интернета (производство, медицина, поле, закрытые сети); свои сроки обновления. Для промышленного оборудования это не бонус, а условие покупки.

Поставщику это стоит мультипликативной матрицы сборок: версии умножаются на платформы, те — на архитектуры, и три ветки × три ОС × две архитектуры дают восемнадцать артефактов, каждый надо собрать, протестировать, подписать и опубликовать. Дальше — невозможность горячего исправления (баг вы чините за час, а доедет он, когда клиент решит обновиться); диагностика вслепую, из которой растёт практика собирать диагностический архив одной командой; совместимость данных на годы, потому что клиент обновляется с версии полуторагодовой давности; подпись и воспроизводимая сборка, раз артефакт живёт без вас (Упаковка, цепочка поставки).

Жизненный цикл одной установленной копии — почти каждое состояние порождает вам работу:

Обязательства коробки. Срок поддержки версии — сколько лет вы чините безопасность в купленной редакции; пишется до продажи, а не после первого CVE. Канал доставки обновлений — куда клиент придёт через два года, когда письмо потерялось, а ссылка протухла. Восстановление доступа: покупатель меняет ноутбук и должен получить свой файл, не покупая второй раз. Поведение при истечении лицензии — мягкая деградация или остановка чужого прода, решать надо заранее. И план выхода: для дорогого корпоративного софта эту роль исторически играет депонирование исходного кода у третьей стороны, но это вопрос договорный, к юристу. Отозвать выданный доступ можно, а уже скачанный файл — нет, поэтому возврат в цифровой коробке всегда сочетание технического механизма и договорного условия (Биллинг).

SaaS: вы стали оператором чужого рабочего дня

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

Поставщику это стоит статьи расходов, которой в коробке нет вообще, — стоимости обслуживания клиента: инфраструктура, трафик, хранилище, сторонние сервисы, доля поддержки. Считать её надо на клиента и на тариф, иначе один крупный клиент на дешёвом тарифе съедает маржу двадцати мелких (юнит-экономика, стоимость облака). Дальше — обязанности оператора: круглосуточное дежурство как часть продукта (дежурство); миграции схемы на живой базе со всеми клиентами сразу; изоляция арендаторов, где ошибка в фильтре по идентификатору превращается в утечку (Многотенантность); чужие данные у вас — юрисдикция, срок удаления, реакция на инцидент (приватность); и измеримая доступность, потому что без измерений вы не знаете, нарушили обещанную цифру или нет (SLI и SLO). Зато исправление доезжает до всех за один цикл выката:

Та же картинка объясняет обратную сторону: одна плохая версия достаётся всем сразу. Как ограничивать радиус поражения — стратегии релизов и безопасные релизы.

Обязательства SaaS. Доступность и способ её измерения. Экспорт данных в машиночитаемом виде без вашего участия — без него переход к вам билет в один конец, и отдел закупок это заметит. Уведомление об изменении цены с разумным сроком, а не письмом за день. Порядок реакции на инцидент безопасности и судьба данных после закрытия аккаунта. Локация данных — для части клиентов это первый вопрос анкеты, а не последний (Ограничения).

Self-hosted: ваш код в чужом контуре

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

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

Обязательства self-hosted. Требования в цифрах, а не «зависит от нагрузки». Матрица поддерживаемых окружений и срок её жизни. Путь обновления через несколько версий сразу — клиент пропустит релизы, это норма. Диагностический пакет, собирающий нужное для обращения и не собирающий лишних персональных данных. Процедура при истечении лицензии: деградация до режима чтения — хорошая практика, остановка прода — способ превратить спор в аварию. Отдельный случай, self-hosted из открытого кода, разбирает Открытый код как способ поставки.

Гибрид: один код, два режима

Гибрид — не «немного того, немного этого», а конкретные конструкции со своей границей: control plane у вас, data plane у клиента (BYOC); SaaS и self-hosted редакции из одного кода; облачный сервис плюс агент в контуре; открытое ядро плюс платное облако.

Инженерная цена гибрида. Две матрицы тестов: каждую функцию проверяют в обоих режимах, иначе контурная редакция молча отстаёт и через год вы поддерживаете две системы под одним именем. Соблазн ветки: on-prem редакцию отпочковывают «на время», и патч безопасности делается дважды — правило простое, различия живут в конфигурации и флагах, а не в ветке. Двойной набор предположений: в облаке есть очередь, объектное хранилище и поисковый движок, в контуре может не быть ничего. И телеметрия документированная, отключаемая, без данных клиента.

from dataclasses import dataclass

@dataclass(frozen=True)
class DeploymentProfile:
    """Различия между редакциями живут ЗДЕСЬ, а не в отдельной ветке."""
    object_storage: str      # s3 | minio | filesystem
    queue: str               # sqs | rabbitmq | postgres
    telemetry: str | None    # None — закрытый контур, телеметрии нет вовсе
    isolation: str           # row | schema | instance
    features: frozenset[str]

PROFILES = {
    "saas": DeploymentProfile("s3", "sqs", "https://telemetry.example.com", "row",
                              frozenset({"billing", "self_serve", "metering"})),
    "self-hosted": DeploymentProfile("filesystem", "postgres", None, "instance",
                                     frozenset({"license_check", "ldap", "offline"})),
}

Смысл не в коде, а в правиле: если различие между редакциями нельзя выразить значением в профиле — вы делаете два продукта. Тест «объединение features по всем профилям совпадает со списком заявленных функций» живёт в конвейере рядом с остальными (окружения).

Обязательства гибрида. Паритет функций и его честные границы: если функция только в облаке, это говорится до продажи. Синхронность патчей безопасности — в контурной редакции патч нужен раньше, его ещё предстоит установить. Прозрачность телеметрии: список уходящих полей — часть документации. Минимальные права в облаке клиента: в BYOC вы просите роль в чужом аккаунте и защищаете её объём перед его безопасниками.

Сколько сборок вы обязаны держать живыми

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

from itertools import product

SUPPORTED_VERSIONS = ["1.4", "1.5", "2.0"]   # три живые ветки
PLATFORMS = ["linux", "windows", "macos"]
ARCHES = ["x86_64", "arm64"]
HOURS_PER_BUILD = 1.5    # в месяц: сборка, тесты, подпись, публикация, проверка
HOURS_PER_BRANCH = 6.0   # в месяц: бэкпорты, ревью, релизные заметки, коммуникация

def build_matrix():
    """Артефакты, которые вы обещали чинить. O(V * P * A) по времени и по памяти."""
    return [(v, p, a) for v, p, a in product(SUPPORTED_VERSIONS, PLATFORMS, ARCHES)]

def monthly_hours():
    return len(build_matrix()) * HOURS_PER_BUILD + len(SUPPORTED_VERSIONS) * HOURS_PER_BRANCH

print(len(build_matrix()), monthly_hours())   # 18 45.0

Восемнадцать артефактов и сорок пять часов в месяц — примерно четверть ставки инженера на поддержание уже проданного, до первой новой строки кода; четвёртая живая ветка добавит ещё пятнадцать часов, лишняя архитектура — двадцать один. Отсюда вывод: срок поддержки версии — это не щедрость, а бюджет. Три живые ветки на команду из шести человек — норма, семь — уже вместо разработки (Обновления и версии). В SaaS эта статья почти исчезает, версия одна, — но расходы растут с числом арендаторов и объёмом их данных и не исчезают, когда вы перестаёте писать код: коробка платит человеко-часами за разнообразие, SaaS — счетами за инфраструктуру и дежурство.

Как выбирают модель

Порядок рассуждения — от ограничений покупателя, а не от вашего удобства. Два вопроса решают почти всё: жёсткость требований к контуру и готовность клиента эксплуатировать софт самому.

Правила, экономящие месяцы:

  • Если треть целевых клиентов не может выпустить данные из контура, стратегия «только SaaS» обрезает рынок — узнавать это надо до того, как архитектура станет многоарендной.
  • Если продукт покупает инженер за свои деньги, а не отдел закупок, самообслуживание важнее любых корпоративных возможностей; если цена ниже стоимости внедрения, не взлетит уже self-hosted.
  • Если продукт трогает деньги или производство, спросят про план выхода и депонирование кода; «мы никогда не закроемся» не засчитывается.
  • Начинать с гибрида редко разумно — он оправдан, когда есть работающая первая модель и клиенты, упирающиеся именно в её ограничение.

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

Смена модели по ходу жизни продукта

Типичная траектория: открытый код → платная коробка → SaaS → гибрид под корпоративного клиента → чужие витрины. Каждый переход — не «переключение тарифа», а работа, которую забывают заложить:

Переход Что ломается
Коробка → SaaS Данные клиентов надо перевезти; лицензия заменяется подпиской; появляются биллинг, дежурство и договор о доступности
SaaS → self-hosted Все предположения об управляемых облачных сервисах; появляются установка, обновление, лицензионные ключи, офлайн-режим
Открытый код → платная редакция Смену лицензии сообщество воспринимает болезненно; нужен честный ответ, что остаётся открытым; вопрос о правах на прошлые вклады — к юристу
Свой сайт → магазин Ваши правила заменяются чужими: ревью, комиссия, ограничения на способы оплаты, отказ без объяснений

Последняя строка — тема глав Каналы поставки, Магазины приложений и Дистрибуция игр.

Деньги: модель поставки ограничивает форму платежа

Продавать потребление там, где вы его не видите, нельзя; брать помесячно за софт, работающий без связи с вами, тоже проблематично.

Модель Естественная форма денег Что технически обязательно
Коробка Разовая покупка версии, отдельно платный апгрейд Учёт прав на скачивание, восстановление доступа, проверка редакции
Коробка корпоративная Бессрочная лицензия плюс годовая подписка на поддержку Учёт срока поддержки, продление, отдельный канал сборок
SaaS Подписка за места или за потребление Воспроизводимый учёт потребления, пропорциональные пересчёты
Self-hosted Годовая лицензия по мощности или узлам Офлайн-проверка лицензии, поведение при превышении, честная деградация
Гибрид Подписка за control plane; ресурсы клиент платит своему облаку Явное разделение, за что берёте вы и за что берёт облако

Исторический ориентир для корпоративной бессрочной лицензии — годовая поддержка порядка 15–25 процентов от цены лицензии; это отраслевая привычка, а не закон, проверяйте по актуальным прайсам вендоров своего сегмента. Формы цены разбирает Ценообразование, цену услуг — бизнес-трек.

Пробный период технически означает разное. В SaaS — флаг и дата на аккаунте: легко сделать, легко продлить, легко злоупотребить, поэтому ограничение ставится на уровень организации, а не почтового ящика. В коробке — сборка с ограничением по времени или ключ с датой; часы на машине клиента переводятся назад, интернета может не быть, поэтому компромисс — мягкая проверка и уменьшенные лимиты, а не криптографическая крепость. В self-hosted — лицензия на 30 дней в файле, и главный вопрос, что произойдёт на 31-й день: останов чужого прода испортит сделку. В гибриде триал живёт в облачной редакции, а корпоративная проверка идёт пилотом по договору.

Апгрейд посреди периода — требование к учёту: посчитать неиспользованный остаток текущего тарифа, зачесть в новый и показать клиенту разложение суммы. Понижение обычно применяют со следующего периода, чтобы не превращать биллинг в кассу возвратов. Возврат в SaaS — прекращение доступа, в коробке — отзыв прав на скачивание, потому что скачанный файл вернуть невозможно (Биллинг).

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

  1. Что именно я продаю с точки зрения права — экземпляр программы, право использования или услугу доступа к сервису? От этого зависит почти всё остальное.
  2. Где считается место реализации при продаже физлицу за рубежом и юрлицу в своей стране?
  3. Кто выступает продавцом при продаже через магазин или платформу и кто обязан выдать покупателю фискальный документ?
  4. Какие документы обязан получить покупатель и в какой момент?
  5. В какой валюте я вправе указывать цену и по какому курсу пересчитывать платёж в другой?
  6. Какие обязательные права потребителя нельзя ограничить моими условиями возврата?
  7. Какие ограничения по странам применимы к продукту — экспортные, санкционные, отраслевые?

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

Обязательства: сводная таблица

Обязательство Коробка SaaS Self-hosted Гибрид
Срок поддержки версии обязателен не нужен, версия одна обязателен, обычно длиннее обязателен для контурной редакции
Восстановление доступа к артефакту обязательно не применимо обязательно обязательно
Заявленная доступность нет обязательна у клиента своя частично, на control plane
Экспорт данных данные и так у клиента обязателен у клиента у клиента
Уведомление об изменении цены при продлении поддержки обязательно при продлении лицензии обязательно
План выхода и депонирование кода часто требуют требуют реже требуют часто требуют
Публикация исходников зависит от лицензий зависимостей зависит, включая сетевой копилефт зависит от лицензий зависит от лицензий

Последняя строка не формальность: раздаёте артефакт — копилефтные лицензии в зависимостях обязывают передать исходники получателю; хостите сервис — часть лицензий требует того же от оператора (Лицензии).

Как это устроено на портале

Digitable Courses — небольшой, но честный пример трёх моделей в одном проекте. Статический сайт: собранная Hugo статика — фактически «SaaS без аккаунтов», пользователь ничего не устанавливает, версия одна, ответственность за доступность на нас. Размещённые инстансы открытых инструментов: портал держит сборку it-tools под GPL-3.0 и Digitable Chat под GPL-2.0-or-later, то есть поставляет чужой код сервисом и бандлом в браузер, и это создало конкретное техническое обязательство — постоянные ссылки на исходники именно тех сборок, которые запущены, в подвале каждой страницы. Не потому что «принято делиться», а потому что лицензия обязывает дать получателю доступ к исходному коду полученной им версии (Лицензии). Цифровой архив Workbench: классическая коробка с серверной фиксацией цены, одноразовой ссылкой, восстановлением по email, обновлениями в границах линеек версий, лицензией на одного пользователя и три устройства и отзывом entitlement при возврате. Три способа поставки — три набора обязательств, каждое реализовано кодом.

Типичные ошибки и профиль поставки

  1. Выбрать SaaS «потому что современно», не спросив клиентов про контур — выясняется на первой корпоративной сделке, когда переделывать поздно.
  2. Продать коробку без политики сроков поддержки — через два года девять живых веток и обязанность чинить их все, ведь обратного вы не говорили.
  3. Отпочковать on-prem редакцию в ветку «на время» — через год это два продукта под одним именем, и каждый патч безопасности делается дважды.
  4. Сделать проверку лицензии жёсткой — продукт встаёт в чужом проде из-за рассинхронизации часов, и коммерческий спор превращается в аварию и публичный отзыв.
  5. Не сделать экспорт данных в SaaS — клиенты чувствуют капкан, закупки пишут это в риски.
  6. Считать выручку и не считать стоимость обслуживания клиента — на безлимитных тарифах один тяжёлый клиент съедает маржу десятков обычных.
  7. Добавить телеметрию в self-hosted тихо — в закрытом контуре это разрыв договора, а не баг-репорт; сюда же — обещать паритет функций и не проверять его в CI.
  8. Забыть про план выхода — «мы работаем над этим» не ответ на вопрос, что будет с системой клиента, если вы закроетесь.

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

# delivery-profile.yaml — договор о том, что мы вообще обещаем
model: hybrid                   # box | saas | self-hosted | hybrid
runs_where: customer_cloud
who_decides_upgrade: vendor_control_plane
versions:
  supported_branches: 2         # сколько веток чиним одновременно
  security_fixes_months: 18     # сколько месяцев чиним безопасность в старой ветке
  upgrade_path: "n-2"           # обновление максимум через две минорные версии
data: { stored_by: customer, export_format: ["jsonl", "csv"], deletion_sla_days: 30 }
telemetry:
  enabled_by_default: true      # и обязательно отключаемо
  fields: ["версия", "статус компонентов", "счётчики ошибок"]
  never_sent: ["содержимое записей", "персональные данные", "имена пользователей"]
money: { form: "подписка за control plane", trial: "30 дней, дальше режим чтения",
         currency: "рубли, цена фиксируется сервером на момент заказа" }
exit: { data_export_without_vendor: true, escrow: "обсуждается для крупных клиентов" }

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

Мини-итог

  • Модель определяют три вопроса: где выполняется код, кто решает про обновление, кто платит за простой; остальное — производные.
  • Коробка даёт покупателю независимость, а поставщику — матрицу сборок, диагностику вслепую и обязанность годами поддерживать миграции. SaaS даёт мгновенный доступ и одну версию, превращая поставщика в оператора: дежурство, чужие данные, стоимость обслуживания клиента.
  • Self-hosted продаётся тем, кто иначе не купит, ценой офлайн-установки, матрицы совместимости и самодиагностики; гибрид снимает это ограничение ценой двух матриц тестов, и спасает его единственное правило — различия в конфигурации, а не в ветке.
  • Обязательства — сроки поддержки, экспорт данных, прозрачность телеметрии, план выхода — дешевле записать до первой продажи. Где вопрос правовой, идите к юристу с конкретной формулировкой: что продаётся, где место реализации, кто продавец, что нельзя ограничить.

Источники

Что дальше

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

IaaS, PaaS, SaaS, FaaS: где кончается ваша ответственность

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

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

Доска запросов