DevOps и инфраструктура

Что происходит после запуска: как устроена техническая поддержка переданного веб-проекта

Разработка закончена. Проект прошёл проверку. Домен подключён. HTTPS работает. Приложение развёрнуто на VPS заказчика. Заказчик получил исходный код, ZIP-архив, документацию, ключи и необходимые доступы. Кажется, что на этом техническая часть заканчивается.

На практике именно с этого момента начинается самая длинная стадия жизни большинства веб-продуктов — эксплуатация.

Через неделю может обновиться внешний API.

Через месяц закончится свободное место на диске.

Через полгода бизнес захочет изменить один из процессов.

Пользователь найдёт редкий сценарий, который невозможно было воспроизвести при обычном тестировании.

Появится новая версия Node.js, PostgreSQL или другой зависимости.

Изменятся требования к интеграции.

Увеличится нагрузка.

Понадобится восстановить случайно удалённые данные.

Поэтому передача проекта заказчику не означает:

Разработчик передал архив и больше никогда к системе не возвращается.

Но и техническая поддержка не должна означать:

Любое пожелание клиента теперь бесплатно и бессрочно входит в первоначальную разработку.

Хорошая модель находится между этими крайностями.

Для этого нужно чётко разделить гарантийные исправления, техническую эксплуатацию, поддержку и дальнейшее развитие продукта.

Разберём, как это может быть устроено.


Передача проекта и техническая поддержка — разные этапы

До передачи система находится в процессе разработки.

Условно:

ТЗ
 ↓
Разработка
 ↓
Тестирование
 ↓
Приёмка
 ↓
Deployment
 ↓
Production
 ↓
Передача проекта

После этого появляется другой жизненный цикл:

Production
   ↓
Мониторинг
   ↓
Обновления
   ↓
Инциденты
   ↓
Исправления
   ↓
Изменения бизнеса
   ↓
Новые версии

То есть после запуска проект перестаёт быть только результатом разработки.

Он становится работающей информационной системой.


Что именно передаётся заказчику

До разговора о поддержке важно определить, что означает сама передача.

В нормальном сценарии заказчик получает контроль над продуктом.

В зависимости от проекта комплект может включать:

исходный код;
готовый release;
ZIP-архив проекта;
документацию;
структуру базы данных;
инструкцию deployment;
инструкцию backup/restore;
production-конфигурацию;
данные о домене;
доступ к VPS;
ключи и секреты;
доступы к внешним сервисам.

Не обязательно все секреты должны лежать прямо внутри ZIP.

Наоборот, чувствительные credentials лучше передавать отдельно и безопасно.

Главный принцип другой:

клиент не должен зависеть от единственной копии проекта, хранящейся только у разработчика.


После передачи инфраструктура должна оставаться под контролем заказчика

Если VPS принадлежит заказчику, домен зарегистрирован на заказчика, а исходники и секреты переданы, клиент сохраняет контроль над своим продуктом.

Это важно и для дальнейшей поддержки.

Заказчик может:

продолжить работу с первоначальным разработчиком;

или:

подключить другого специалиста;

или:

создать собственную техническую команду.

Техническая поддержка в таком случае является услугой.

Не механизмом удержания проекта.


Первая граница: дефект или новая функция?

Это, пожалуй, самый важный вопрос после запуска.

Представим техническое задание:

Клиент может загрузить PDF размером до 20 МБ.

После deployment выясняется:

PDF до 5 МБ → работает
PDF 8 МБ → сервер возвращает ошибку

Если ограничения в ТЗ не было и согласованная функция должна работать до 20 МБ, перед нами дефект реализации или production-конфигурации.

Теперь другой запрос:

Давайте после загрузки PDF автоматически распознавать его содержимое и отправлять результат в 1С.

Этого в исходном ТЗ не было.

Это уже:

новая функциональность.

Разница принципиальна.


Поддержка не должна превращать первоначальное ТЗ в бесконечный список

После запуска продукта у бизнеса неизбежно появляются идеи.

Например:

добавить Telegram;
подключить новую CRM;
изменить workflow;
добавить AI-анализ;
создать новый тип пользователя.

Все эти идеи могут быть отличными.

Но они изменяют продукт.

Поэтому полезно разделять:

Исправление

и:

Изменение

Практический критерий

Можно задать один вопрос:

Система сейчас делает то, что было согласовано?

Если:

нет

вероятно, речь идёт об исправлении.

Если:

да, но теперь мы хотим иначе

это изменение требований.


Почему такое разделение защищает обе стороны

Без него заказчик может считать:

Раз проект поддерживается, любую новую функцию должны добавить в поддержку.

Разработчик:

Раз проект передан, всё новое теперь платно — даже исправление явной ошибки.

Обе крайности создают конфликт.

Понятная классификация устраняет большую часть споров.


Мы бы разделили послепроектную работу на четыре категории

Условно:

1. Гарантийные дефекты

2. Эксплуатационная поддержка

3. Техническое обслуживание

4. Развитие продукта

Это четыре разных типа работы.


1. Гарантийные дефекты

Это ситуации, когда реализованная функция не соответствует согласованному поведению.

Например:

регистрация должна работать,
но возвращает 500;
роль VIEWER видит данные,
которые по ТЗ видеть не должна;
кнопка экспорта должна создавать XLSX,
но файл повреждён;
мобильная версия
ломается на согласованном разрешении.

Здесь вопрос не в развитии продукта.

Нужно восстановить согласованное поведение.


Но не каждая production-ошибка автоматически является дефектом разработки

Представим:

внешний сервис изменил API.

Или:

владелец VPS самостоятельно
изменил firewall.

Или:

домен не был продлён.

Или:

провайдер прекратил поддержку
старой версии API.

Приложение может перестать работать, хотя исходная реализация была корректной.

Это уже эксплуатационная проблема.


2. Эксплуатационная поддержка

Она отвечает на вопрос:

Что делать, если работающая production-система столкнулась с проблемой?

Например пользователь сообщает:

Не приходит письмо восстановления пароля.

Нельзя сразу предполагать:

баг приложения.

Причиной может быть:

SMTP;
DNS;
SPF/DKIM;
лимит почтового сервиса;
очередь;
worker;
ошибка конкретного адреса.

Поддержка сначала диагностирует причину.


Нормальный процесс инцидента выглядит примерно так

Сообщение о проблеме
        ↓
Регистрация инцидента
        ↓
Диагностика
        ↓
Определение причины
        ↓
┌───────────────┬────────────────┐
│               │                │
▼               ▼                ▼
Defect      Infrastructure   External service
│               │                │
▼               ▼                ▼
Fix          Recovery          Adaptation
        ↓
Проверка production
        ↓
Закрытие инцидента

Это значительно эффективнее:

Что-то не работает — давайте срочно менять код.

Сначала нужно определить влияние проблемы

Не все ошибки одинаково критичны.

Например:

На странице настроек неправильный отступ.

и:

Все пользователи потеряли возможность войти.

— это разные инциденты.

Поэтому поддержка обычно требует приоритизации.


Пример простой шкалы критичности

P1 — критический инцидент

Основной продукт недоступен или нарушена критическая функция.

Например:

сайт полностью недоступен;
невозможно авторизоваться;
платежи подтверждаются неправильно;
существует риск утечки данных.

Такая задача получает максимальный приоритет.


P2 — серьёзная проблема

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

Например:

не загружаются файлы;
не работает интеграция с CRM;
не отправляются email.

P3 — обычный дефект

Есть обходной путь.

Например:

один фильтр работает неправильно;

или:

в определённом сценарии
не обновляется уведомление.

P4 — улучшение

Например:

изменить подпись;
улучшить расположение блока;
добавить дополнительный фильтр.

Последнее уже часто является скорее развитием, чем инцидентом.


SLA нужно определять не красивыми словами, а измеримыми правилами

Фраза:

Быстро исправляем проблемы.

почти ничего не означает.

Полезнее определить:

время реакции;
рабочие часы;
критичность;
канал обращения;
порядок эскалации.

Например:

P1 → приоритетная реакция

P2 → высокая

P3 → обычная очередь

P4 → план изменений

Конкретные сроки должны определяться условиями поддержки конкретного проекта.


Время реакции и время исправления — не одно и то же

Это особенно важно.

Можно гарантировать:

Начинаем анализ P1 в определённый срок.

Но невозможно заранее гарантировать:

Любая критическая ошибка будет полностью исправлена за 30 минут.

Причина может оказаться:

в аварии дата-центра;
во внешнем API;
в повреждении данных;
в сетевой инфраструктуре.

Поэтому профессиональнее отдельно определять:

response time

и:

resolution process.

Хорошая поддержка начинается с наблюдаемости

Самая дорогая ошибка:

Узнать о падении приложения от клиента.

Работающий production желательно контролировать автоматически.

Например:

HTTPS доступен?
API отвечает?
PostgreSQL доступен?
Redis работает?
достаточно ли диска?
worker выполняет задачи?
backup не устарел?
растёт ли число ошибок?

Мониторинг не гарантирует отсутствие аварий

Он решает другую задачу:

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

Например без мониторинга:

03:00
диск заполнен

08:40
первый пользователь сообщает об ошибке

С мониторингом:

03:00
disk free < threshold

03:01
alert

Это принципиально другая эксплуатация.


Health и readiness — разные проверки

Например Node.js process работает.

Значит:

process alive = true

Но PostgreSQL недоступен.

Приложение физически существует, однако обслуживать пользователей не может.

Поэтому полезно различать:

Health
→ процесс жив

и:

Readiness
→ необходимые зависимости доступны

Например:

API       ✓
PostgreSQL ✗
Redis      ✓
Storage    ✓

Ready: NO

Так диагностика становится намного точнее.


Поддержка должна видеть журналы

Представим пользователь сообщает:

В 15:43 не получилось загрузить договор.

Без observability остаётся:

Попробуйте ещё раз.

С нормальными логами можно найти:

15:43:12
requestId = ...
userId = ...
POST /files

а затем:

storage timeout

или:

file limit exceeded

или:

permission denied

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


Но логирование не означает «записывать всё подряд»

Логи не должны бесконтрольно содержать:

пароли;
секретные токены;
полные пользовательские документы;
платёжные реквизиты.

Поддержке обычно нужны:

request ID;
user ID;
route;
status;
error code;
timestamp;
dependency;

а не все чувствительные данные пользователя.


Техническая поддержка невозможна без нормальной backup-стратегии

Представим приложение работает идеально.

Но администратор случайно удалил важную запись.

Это уже не вопрос:

Как исправить код?

Нужно:

Можно ли восстановить данные?

Поэтому backup — часть поддержки production.


Сам факт существования backup ещё ничего не гарантирует

Например:

backup.sql

создаётся ежедневно.

Но никто никогда не проверял:

можно ли его восстановить?

Такой backup имеет неопределённую ценность.

Правильный жизненный цикл:

Создать backup
        ↓
Проверить целостность
        ↓
Хранить
        ↓
Периодически проверять restore

Резервная копия должна быть независима от основной инфраструктуры

Если production:

VPS #1

и единственный backup тоже:

VPS #1

при потере всего сервера можно потерять одновременно:

production
+
backup.

Для серьёзного проекта полезна offsite-копия.


При этом backup базы и backup файлов — разные вещи

Представим:

PostgreSQL backup ✓

но пользовательские документы находятся:

/var/lib/app/uploads

и не копируются.

После аварии восстановятся:

users
projects
file metadata

но сами PDF исчезнут.

Поэтому recovery plan должен учитывать весь state продукта.


Техническая поддержка включает контроль свободного места

На одном VPS могут одновременно расти:

PostgreSQL;
логи;
backup;
Docker layers;
releases;
uploads;
temporary files.

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

ENOSPC

То есть файловая система просто откажется записывать данные.

До этого лучше не доводить.


В production нужен резерв свободного места

Например нельзя рассуждать:

На диске осталось 2 ГБ, а файл занимает 1,9 ГБ — значит он помещается.

PostgreSQL, логам и deployment тоже требуется место.

Поэтому используется operational reserve:

free disk
-
projected operation
>=
safety reserve

Такая защита особенно важна для продуктов с пользовательскими файлами.


Логи тоже имеют retention

Плохая схема:

application.log

растёт бесконечно.

Через несколько месяцев:

120 GB

и приложение падает не из-за бизнес-нагрузки, а из-за собственного журнала.

Поэтому production support включает:

rotation;
compression;
retention;
maximum size.

Следующий слой — обновление зависимостей

Веб-продукт редко работает пять лет на абсолютно неизменном стеке.

Есть:

Node.js;
npm packages;
PostgreSQL;
Nginx;
Docker;
операционная система.

Со временем появляются новые версии и security updates.


Но обновлять всё автоматически в production тоже опасно

Стратегия:

npm update
↓
deploy

может неожиданно изменить:

API библиотеки;
поведение ORM;
frontend;
build.

Поэтому обновление — управляемая операция.


Нормальный процесс обновления

Проверить изменения
        ↓
Обновить dependency
        ↓
Unit / integration tests
        ↓
Build
        ↓
Staging
        ↓
Regression tests
        ↓
Production deployment
        ↓
Post-deploy checks

Для маленькой security patch часть этапов может быть автоматизирована.

Но принцип сохраняется:

production не должен становиться первым местом, где проверяется новая версия.


То же относится к обновлению самой ОС

Например VPS работает:

Ubuntu

Системные пакеты требуют обновлений.

Но некоторые изменения могут потребовать:

restart;

или даже:

reboot.

Поэтому для production полезно иметь maintenance window.


Maintenance window — заранее известное окно обслуживания

Например:

ночь;
выходные;

или другое время минимальной нагрузки.

Именно туда можно планировать:

обновление ОС;
major PostgreSQL maintenance;
сложную миграцию;
изменение infrastructure.

Не каждую операцию нужно выполнять срочно днём.


Security support — отдельная часть сопровождения

Проект после передачи продолжает находиться в интернете.

Значит, появляются:

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

Поддержка должна учитывать security lifecycle.


Например, секрет однажды может потребовать замены

API-key внешнего сервиса:

скомпрометирован;

или:

провайдер требует rotation.

Хорошая архитектура позволяет:

создать новый ключ;
обновить production secret;
перезапустить сервис;
отозвать старый.

Без изменения исходного кода.


Пароли и ключи нельзя хранить только «у разработчика»

После передачи продукта заказчик должен понимать:

где находятся production secrets;
кому они доступны;
как их заменить;
какие ключи принадлежат внешним сервисам.

Поддержка не должна зависеть от памяти одного человека.


Документация здесь становится особенно важной

Когда проект только разработан, автор и так помнит:

как запустить worker;
где environment;
как сделать backup.

Через два года эти знания уже не гарантированы.

Поэтому документация должна превращать:

Я знаю, как это работает.

в:

Команда знает, как это работает.

Минимальный эксплуатационный документ может отвечать на вопросы

Как развёрнут проект?

Какие сервисы должны работать?

Как проверить readiness?

Как посмотреть логи?

Как выполнить backup?

Как восстановиться?

Как обновить приложение?

Как откатить release?

Где находятся данные?

Какие внешние интеграции используются?

Это резко сокращает стоимость будущей поддержки.


Почему rollback должен существовать до первого проблемного обновления

Представим release:

v2.4

После deployment выясняется:

редкий, но критичный сценарий сломан.

Плохой план:

Сейчас срочно разберёмся, как вернуть старую версию.

Хороший:

current
→ v2.4

previous
→ v2.3

и заранее протестированная процедура отката.


Но rollback приложения и rollback базы — разные задачи

Код можно вернуть:

v2.4 → v2.3

за секунды.

Но если v2.4 уже выполнил необратимую database migration, старый код может больше не понимать новую схему.

Поэтому database migration тоже должна проектироваться с учётом deployment.


Например, безопаснее расширять схему постепенно

Вместо:

удалить old_column
и сразу использовать new_column

можно:

Release A:
добавить new_column
Release B:
перенести данные
Release C:
перейти на новое поле
Release D:
удалить старое

Это увеличивает совместимость releases и облегчает rollback.


Внешние интеграции — один из главных источников поддержки

Даже если ваш код не меняется, меняются внешние системы.

Например:

CRM API;
1С;
платёжный провайдер;
SMTP;
карты;
AI API.

Они могут:

изменить endpoint;
закрыть старую версию;
ввести новый лимит;
изменить authentication.

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


Поэтому интеграция должна быть диагностируемой

Плохо:

Синхронизация не работает.

Хорошо:

CRM integration

Last success:
08:42

Last attempt:
08:47

Status:
FAILED

Reason:
HTTP 401

Action:
credentials require renewal

Тогда поддержка быстрее определяет причину.


Retry не должен создавать дубли

Представим синхронизацию заказа.

Первый запрос к внешней системе фактически создал заказ, но ответ потерялся.

Поддержка нажимает:

[Повторить]

Если операция неидемпотентна, появится второй заказ.

Поэтому даже административные recovery-действия должны учитывать:

idempotency;
external ID;
state reconciliation.

Кнопка «Повторить» не должна означать «создать ещё раз».


Хорошая админ-панель сильно упрощает поддержку

Например администратор может самостоятельно:

посмотреть состояние интеграции;
повторить безопасную failed job;
перепубликовать статью;
заблокировать пользователя;
проверить статус backup;
увидеть объём диска.

Это снижает количество обращений к разработчику по обычным операционным вопросам.


Но админка не должна давать root-доступ

Показывать:

Storage: 76%

нормально.

Кнопка:

rm -rf /var/lib/app

в админке очевидно не нужна.

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


Что делать, если проблема появилась после действий заказчика

Представим заказчик самостоятельно изменил:

DNS;
Nginx;
environment;
database.

После этого продукт перестал работать.

Это не обязательно означает дефект исходной разработки.

Но поддержка всё равно может:

провести диагностику;
восстановить конфигурацию;
объяснить причину.

Такая работа относится уже к эксплуатации.


Поэтому полезен audit инфраструктурных изменений

Для большого продукта важно понимать:

кто;
когда;
что изменил.

Если все используют один root account:

root

расследование значительно сложнее.

Отдельные учётные записи и журналирование лучше.


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

Плохая модель:

разработчик навсегда знает
главный root-пароль клиента.

Лучше:

отдельный технический аккаунт;

или:

временный доступ
на время работ.

После завершения поддержки его можно отозвать.


Особенно аккуратно нужно работать с production-данными

Чтобы исправить интерфейс, разработчику не обязательно скачивать:

всю базу клиентов;
все документы;
всю переписку.

Для воспроизведения проблемы лучше использовать:

staging;
анонимизированные данные;
минимальный test case.

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


Staging сильно уменьшает риск поддержки

Хорошая схема:

Development
     ↓
Staging
     ↓
Production

Новая версия сначала попадает на staging.

Там выполняются:

migration;
build;
smoke tests;
integration tests.

Только потом production.


Для небольшого проекта staging может быть проще

Не обязательно создавать огромную инфраструктуру.

Это может быть:

отдельный контейнер;
отдельная база;
временная среда перед release.

Главное — не тестировать рискованное изменение впервые на живых клиентах.


Техническая поддержка и развитие — это разные очереди работ

Допустим одновременно существуют:

P1:
не проходит авторизация

и:

Feature:
добавить новый dashboard.

Очевидно, сначала нужно вернуть работу основной функции.

Поэтому incident queue и roadmap полезно разделять.


Пример: клиент хочет новую функцию после запуска

Запрос:

Добавить согласование документов через Telegram.

Поддержка фиксирует:

Change Request

Далее определяется:

что именно нужно;
затронутые модули;
срок;
стоимость;
риски.

После подтверждения это становится обычной новой разработкой.


Это позволяет продукту развиваться контролируемо

Вместо:

Добавьте ещё вот эту маленькую кнопку.

появляется процесс:

Идея
 ↓
Уточнение
 ↓
Оценка
 ↓
Согласование
 ↓
Разработка
 ↓
Тестирование
 ↓
Release

Даже небольшое изменение проходит разумный объём контроля.


Маленькое изменение иногда совсем не маленькое

Например:

Добавить статус «Приостановлен».

В интерфейсе это действительно одна строка.

Но нужно решить:

кто может поставить статус;
можно ли писать сообщения;
остановится ли SLA;
что будет с уведомлениями;
видит ли его клиент;
как вернуть проект в работу.

Поэтому поддержка не должна оценивать сложность по размеру кнопки.


Хорошая поддержка знает архитектуру, а не только код

Например:

Не приходит уведомление.

Причина может лежать в:

frontend;
backend;
database;
queue;
worker;
SMTP;
DNS.

Нужно понимать путь события:

User action
   ↓
API
   ↓
PostgreSQL
   ↓
Job
   ↓
Worker
   ↓
SMTP
   ↓
Recipient

И диагностировать каждый уровень.


Именно поэтому архитектурная документация экономит деньги

Без неё новый разработчик начинает с:

Сейчас разберёмся, как тут всё связано.

С ней:

API #1/#2
PostgreSQL
Redis
Object Storage
Worker
Nginx

уже описаны.

Часы изучения превращаются в минуты ориентации.


Поддержка должна учитывать рост продукта

Проект запускается с:

100 пользователями.

Через год:

20 000.

То, что прекрасно работало сначала, может потребовать изменений.

Например:

новые индексы;
pagination;
cache;
background processing;
масштабирование API.

Это уже не defect.

Это развитие инфраструктуры под новые условия эксплуатации.


Поэтому performance monitoring полезен до проблем

Например отслеживаются:

p95 latency;
database query time;
error rate;
CPU;
RAM;
disk;
queue depth.

Тогда можно заметить постепенное ухудшение до того, как система станет неудобной для пользователей.


Оптимизировать заранее всё подряд тоже не нужно

Если:

CPU = 4%

и:

p95 = 120 ms

нет смысла срочно строить:

Kubernetes;
Kafka;
10 replicas.

Техническая поддержка должна опираться на реальные метрики.

Не на архитектурную моду.


Пример нормальной эволюции

Первая версия

1 VPS
PostgreSQL
Nginx
API
Worker

Рост

Появляется:

API #1
API #2

Ещё позже

Отдельный:

Object Storage

или:

managed database.

То есть сопровождение может постепенно менять инфраструктуру без полного переписывания продукта.


Поддержка нужна и SEO-системам

Если продукт имеет публичный сайт, нужно следить не только за backend.

Например:

robots.txt;
sitemap;
canonical;
HTTP status;
SSR;
редиректы;
скорость загрузки.

После изменения маршрутов можно случайно получить:

404;

или:

duplicate pages.

Поэтому production release должен включать проверку публичной части.


После каждого релиза нужна короткая проверка production

Не обязательно запускать весь многоминутный E2E-набор прямо на боевой базе.

Но полезно проверить критические сценарии:

главная открывается;
API ready;
login доступен;
основные страницы отвечают;
новая функция работает.

Это smoke test.


Автоматизация особенно полезна именно в поддержке

Например deployment автоматически выполняет:

build
↓
tests
↓
migration check
↓
release
↓
readiness
↓
post-deploy smoke

Если проверка не проходит:

STOP

или:

rollback

Чем меньше критических действий выполняется вручную, тем ниже вероятность человеческой ошибки.


Но автоматизация должна оставаться диагностируемой

Плохо:

Update failed.

Хорошо:

Stage:
database migration

Migration:
20260928_add_project_state

Error:
constraint violation

Поддержка должна понимать не только:

Что-то не получилось.

Но:

Где именно остановился процесс?

Как может выглядеть обычное обращение в поддержку

Например:

Клиент не может скачать файл проекта.

Сначала фиксируется:

project;
user;
примерное время;
ошибка.

Проверяется:

authorization;
metadata;
object storage;
signed URL;
logs.

Выясняется:

файл существует;
права корректны;
storage отвечает;
signed URL формируется с неправильным TTL.

Исправление создаётся.

Проходит тест.

Разворачивается.

Production проверяется.

Инцидент закрывается.

Это инженерный процесс.

Не просто переписка:

У меня не работает.
А сейчас?

Чем лучше пользователь описал проблему, тем быстрее диагностика

Хорошее обращение:

Пользователь:
client@example.com

Проект:
#1842

Время:
14:32

Действие:
скачивание PDF

Ошибка:
«Не удалось получить файл»

Намного полезнее:

Всё сломалось.

Поэтому интерфейс поддержки может автоматически передавать technical context.


Но клиент не должен собирать stack trace

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

Ему достаточно описать:

что хотел сделать;
что произошло;
когда.

Остальное должна помочь найти техническая система.


Форматы последующей поддержки могут быть разными

Не каждому проекту нужен круглосуточный отдельный инженер.

Обычно возможны несколько моделей.

Поддержка по обращению

Подходит небольшому стабильному проекту.

Появилась задача:

оценили
↓
выполнили
↓
закрыли

Пакет часов

Например бизнес регулярно имеет небольшие технические задачи.

Выделяется определённый объём времени.

Он используется на:

диагностику;
обновления;
мелкие изменения.

Регулярное сопровождение

Подходит работающему бизнес-продукту.

Может включать:

monitoring;
backup checks;
обновления;
инциденты;
плановые releases.

Отдельное развитие

Для крупных новых модулей:

новое ТЗ;
новая оценка;
новый scope.

Это фактически следующий проект внутри существующего продукта.


Какой формат выбрать

Нужно смотреть на цену простоя.

Если небольшой внутренний инструмент недоступен два часа:

неприятно.

Если интернет-магазин с большим оборотом недоступен два часа:

прямые финансовые потери.

Поэтому стоимость и интенсивность поддержки должны соответствовать реальному бизнес-риску.


Нет смысла покупать enterprise-support для маленькой страницы

И наоборот.

Для SaaS, который обслуживает тысячи платящих пользователей, модель:

Напишите разработчику в мессенджер, когда что-нибудь сломается.

слишком хрупкая.

Техническая поддержка должна расти вместе с ценностью продукта.


Какие данные полезно хранить по обращениям

Например:

номер;
тип;
приоритет;
дата;
ответственный;
причина;
исправление;
release.

Через год это позволяет увидеть:

какие проблемы повторяются;
какой модуль ломается чаще;
какие интеграции нестабильны.

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


Root cause важнее временного исправления

Представим:

worker падает раз в неделю.

Можно каждый раз:

restart.

Это workaround.

Но поддержка должна однажды ответить:

Почему он падает?

Например:

утечка памяти;
необработанный файл;
timeout внешнего API.

После устранения причины десятки будущих инцидентов исчезнут.


Полезно различать mitigation и fix

Например production недоступен.

Сначала можно:

переключить конфигурацию

и быстро восстановить работу.

Это mitigation.

Затем спокойно исправить источник проблемы.

Это fix.

При критическом инциденте восстановление сервиса часто важнее немедленного поиска идеального архитектурного решения.


Хорошая поддержка не экспериментирует на production во время аварии

Сценарий:

Не знаем, попробуем обновить три пакета и посмотрим.

опасен.

Лучше:

собрать факты;
локализовать проблему;
минимально изменить;
проверить;
задокументировать.

Production incident требует больше дисциплины, а не меньше.


После серьёзного инцидента полезен короткий postmortem

Не для поиска виноватого.

А для ответа:

Что произошло?

Почему?

Почему мониторинг не поймал раньше?

Что восстановило работу?

Что изменить,
чтобы не повторилось?

Например:

Причина:
disk filled by logs

Исправление:
rotation + maxsize

Предотвращение:
disk alert at 20%

Один инцидент улучшает всю систему.


Когда поддержка перестаёт быть поддержкой и становится модернизацией

Представим приложение написано пять лет назад.

Бизнес хочет:

полностью новый frontend;
другую модель данных;
новую систему ролей;
разделить монолит.

Это уже не обычная эксплуатация.

Это техническое развитие или модернизация.

Для неё нужен отдельный анализ.


Поддерживать любой legacy бесконечно не всегда разумно

Иногда стоимость:

латать старую архитектуру

становится выше:

контролируемой модернизации.

Хорошая техническая поддержка должна уметь сказать об этом заранее.

Не ждать полного отказа системы.


Что в итоге остаётся у заказчика

Хорошая схема передачи и последующей поддержки выглядит примерно так:

Готовый проект
        ↓
Production deployment
        ↓
Проверка
        ↓
Передача исходников
        ↓
Передача документации
        ↓
Передача доступов
        ↓
Заказчик контролирует продукт
        ↓
┌────────────────────┐
│                    │
▼                    ▼
Самостоятельная   Поддержка
эксплуатация      разработчиком
                      │
          ┌───────────┼───────────┐
          ▼           ▼           ▼
       Defects     Operations   Development

То есть передача не создаёт зависимости.

А поддержка не прекращает ownership заказчика.


Как выглядит здоровая граница ответственности

Заказчик отвечает за бизнес-решения

Например:

какую функцию развивать;
какие сотрудники имеют доступ;
какой тариф VPS оплачивать;
какие внешние сервисы использовать.

Техническая команда отвечает за инженерную реализацию

диагностику;
deployment;
безопасные обновления;
исправления;
архитектурные изменения.

Чем яснее граница, тем проще долгосрочная работа.


Техническая поддержка начинается ещё во время разработки

Это, пожалуй, самая важная мысль.

Если проект изначально не имеет:

логов;
backup;
health checks;
rollback;
документации;
контролируемых migrations,

после запуска всё это придётся добавлять в аварийном режиме.

Поддерживаемость — архитектурное свойство.

Её нельзя полностью «докупить потом».


Хороший код — не единственное условие поддерживаемости

Можно написать идеально структурированное приложение.

Но если неизвестно:

какая версия сейчас production;
когда был backup;
где логи;
как откатиться;

поддерживать его всё равно тяжело.

Production engineering включает код и эксплуатационный контур одновременно.


Поэтому при передаче полезен эксплуатационный чек-лист

Например:

[✓] Production URL

[✓] VPS access

[✓] Domain/DNS

[✓] HTTPS

[✓] Database

[✓] Backup

[✓] Restore instruction

[✓] Worker

[✓] Logs

[✓] Monitoring

[✓] Secrets

[✓] Source archive

[✓] Documentation

[✓] Deployment instruction

[✓] Rollback procedure

Так проект передаётся как система.

Не просто как папка с исходным кодом.


Как понять, что продукт действительно можно поддерживать

Есть хороший тест.

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

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

Где приложение?
Как оно запускается?
Где база?
Как сделать backup?
Как безопасно выпустить новую версию?
Где посмотреть ошибку?
Как откатить release?

Если ответ:

да, всё описано

проект действительно передан.

Если:

Нужно спросить автора, он единственный знает.

существует сильная техническая зависимость.


Вместо вывода

Передача веб-проекта не должна означать конец его технической жизни.

Наоборот.

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

эксплуатация;
мониторинг;
обновления;
инциденты;
развитие.

Но качественная поддержка не означает, что заказчик остаётся навсегда привязан к разработчику.

Правильная модель выглядит иначе.

Сначала клиент получает полноценный продукт:

production;
исходники;
документацию;
доступы;
контроль над инфраструктурой.

После этого техническая команда может продолжать сопровождение как отдельный инженерный процесс.

При этом чётко различаются:

дефект согласованной функции;
production-инцидент;
плановое обслуживание;
новое требование.

Проект наблюдается.

Backup проверяется.

Обновления сначала тестируются.

Критичные изменения имеют rollback.

Внешние интеграции диагностируются.

А новые функции проходят новый цикл оценки и разработки.

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

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

Разработчик не превращается в человека, которому бессрочно отправляют любые задачи под формулировкой «это же поддержка».

А сам веб-продукт получает то, что особенно важно после первого release:

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

Есть похожая задача?

Опишите продукт, интеграции и ограничения. До разработки зафиксируем объём, риски и критерии приёмки.

Обсудить проект →