Cursor и Claude Code уже умеют за вечер собрать то, на что раньше уходила неделя. Интерфейс, API, авторизация, база, какой-нибудь бот сбоку. Ты сидишь, киваешь умному терминалу и постепенно начинаешь верить, что будущее наконец наступило.

А потом приложение нужно выложить в интернет.

И тут мы бежим к Сереге девопсеру и просим его - сделай, бро, красиво.

Начинаются Dockerfile, registry, CI/CD, переменные окружения, DNS, TLS, healthcheck, миграции, логи и вопрос, на каком порту вообще слушает этот код. Вчера ИИ спорил с тобой об архитектуре, а сегодня ты снова копируешь токен в настройки и выясняешь, почему контейнер десятый раз перезапускается.

В начале лета мы с товарищем решили, что в этой картине что-то не так и тут прямо есть где разгуляться. Он DevOps-инженер. Я разработчик и серийный Айти-предприниматель, который слишком часто открывает новый репозиторий со словами:

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

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

Если Клодыч или Кодексявич уже понимают проект и пишут для него код, почему они не могут сами довести этот проект до работающего https?

Так мы полезли строить свою инфраструктуру (амбициозно?), которой можно управлять прямо из Cursor или Claude Code через MCP. Думали, что соединим несколько API, завернём Kubernetes в красивую ручку и довольно быстро пойдем пить кофе.

Разумеется, все оказалось немного интереснее.

Вот примерно с таким мы сейчас сталкиваемся, когда хотим задеплоить код
Вот примерно с таким мы сейчас сталкиваемся, когда хотим задеплоить код

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

На самом верхнем уровне задача звучит почти неприлично просто:

  1. Забрать у юзера (вайбкодера) его чудо-юдо код

  2. Собрать докер-образ

  3. Запустить все это в Kubernetes

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

Если бы все приложения состояли из одного процесса, слушали порт 8080 и не нуждались ни в чем, кроме солнечного света, на этом можно было бы закончить.

Но произвольный пользовательский проект выглядит иначе. В нем может быть публичный веб-интерфейс, внутренняя апишечка, фоновый воркер, Telegram-бот и процесс для обработки очереди. Одному компоненту нужен HTTP-доступ, второй должен быть виден только внутри кластера, а третьему сеть вообще не нужна. Все они могут использовать одну базу, разные базы или еще Redis(ку) со сметанкой.

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

То есть реальная задача звучит уже так:

Как превратить человеческое намерение «выложи вот это» в проверяемое описание production-среды?

И вот здесь AI действительно полезен. Он уже находится внутри проекта, видит дерево файлов и читает исходники. Он может найти команды запуска, обращения к process.env или os.getenv, понять, что перед ним FastAPI, Next.js или несколько процессов в одном репозитории.

Но «может понять» и «имеет право управлять инфраструктурой» все-таки не одно и то же.

Зачем здесь MCP

Самый простой путь выглядел так: дать агенту доступ к git, kubernetes, вольту, registry и пожелать удачи.

Мы решили не проверять, насколько быстро эта идея превратится в увлекательный айти хоррор.

Вместо этого между агентом и платформой появился MCP-сервер. По сути, это небольшой предметный язык деплоя. Агенту не нужно знать, как устроен кластер и в каком репозитории лежат инфраструктурные манифесты. Он получает ограниченный набор операций:

  • запросить актуальную схему проекта

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

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

  • создать проект

  • загрузить исходный код

  • отдельно передать секреты

  • проверить состояние деплоя и получить URL

MCP при этом остается тонким слоем. Он не хранит бизнес-логику и собственные учетные данные, а передает запросы в backend от имени пользователя. Его задача в другом: дать агенту ровно те возможности, которые нужны для деплоя, и не выдать ему связку ключей от всего здания.

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

Высокоуровневая операция create_project для агента гораздо надежнее, чем инструкция:

создай репу, выпусти ключ, положи манифест туда, а если API вернёт 409, попробуй понять почему

Схема от кода до https и задеплоенной апки в интернете
Схема от кода до https и задеплоенной апки в интернете

Что происходит после фразы «задеплой это»

Пользователь пишет в Cursor или Claude Code что-то вроде:

Давай теперь выложим это приложение.

Дальше начинается цепочка, которую снаружи хотелось бы не видеть вообще.

Сначала агент анализирует репозиторий. Он определяет, какие процессы есть у проекта, что из них должно быть публичным, какие порты и команды запуска используются, нужны ли базы данных и какие переменные окружения читает код.

Затем агент получает от MCP схему нашего проекта (контракт с нашей системой) и формирует декларативное описание приложения. В нем есть три простые сущности:

  • публичное приложение с URL и портом

  • внутренний сервис с портом, но без внешнего URL

  • фоновый процесс без порта и маршрута

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

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

После создания проекта backend размещает его в изолированном пространстве пользователя, создает приватный гит-репозиторий, готовит сиайсиди и GitOps-конфигурацию, резервирует домен и связывает все это с конкретным аккаунтом.

Код загружается в репозиторий. CI собирает контейнер, отправляет его в registry и фиксирует версию образа. Flux видит изменение и приводит кластер к нужному состоянию. Оператор создает приложения, сервисы, маршруты и базы данных, а наружу в итоге появляется https-адрес.

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

Четыре места, где мы особенно повеселились

1. Код не помещается в MCP-вызов

Для маленького примера можно передать агентному инструменту список файлов. Для реального проекта это быстро перестает работать. Один lock-файл иногда весит больше, чем весь разумный payload MCP-вызова.

Поэтому MCP создает проект и возвращает отдельный адрес загрузки. Агент упаковывает локальное дерево и передает архив напрямую в backend потоковым запросом. Backend уже раскладывает файлы и фиксирует их в Git. Сам агент прямого доступа к Git не получает.

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

2. Код и секреты нельзя везти одним маршрутом

Исходники должны попасть в Git. Боевые токены, пароли и ключи там оказаться не должны никогда, даже в приватном репозитории и даже «на один коммит, потом удалим».

Агент сканирует код и составляет список переменных окружения. Из него исключаются значения, которые создает сама платформа, например параметры подключенной базы. Остальные секреты передаются отдельной операцией в Vault и доставляются приложениям через External Secrets.

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

3. «Проект создан» не значит «проект работает»

Создание записи в backend занимает мгновения. Настоящий деплой проходит через Git, webhook, CI, registry, Flux, Kubernetes scheduler и healthcheck. Даже успешная сборка еще не гарантирует, что контейнер не упал через секунду из-за миграции или забытой переменной.

Поэтому агенту нельзя просто ответить 200 OK и показать красивую ссылку. Ему нужен фактический статус: код принят, образ собирается, синхронизация идет, приложение запущено, проверка здоровья пройдена.

Только после этого URL можно считать результатом, а не обещанием.

4. Агент иногда слишком уверен в себе

AI может великолепно найти Dockerfile и тут же уверенно придумать несуществующий namespace. Может увидеть три процесса и решить, что наружу нужны все три. Может взять значения из .env.example, хотя там лежат декоративные пароли changeme.

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

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

Задача четырех проблем: Большой архив + Секреты отдельно от Гита + асинхронная цепочка + уверенный ИИ
Задача четырех проблем: Большой архив + Секреты отдельно от Гита + асинхронная цепочка + уверенный ИИ

А разве PaaS уже не решил эту задачу?

Современные PaaS действительно очень многое делают за разработчика. Vercel умеет разворачивать проекты из Git и через CLI. Render позволяет описывать несколько сервисов декларативно. Fly.io анализирует локальный проект, создает конфигурацию и запускает приложение через fly launch. Это зрелые инструменты, которые отлично автоматизируют сборку и выполнение уже подготовленного проекта.

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

В классическом сценарии центром процесса остается разработчик. Он выбирает репозиторий, определяет build-команду, указывает порты, создает базы, заполняет переменные окружения, настраивает домен и разбирается с ошибками сборки.

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

Как выполнить уже сформулированную конфигурацию?

Мы попробовали задать вопрос на один уровень выше:

Кто сформулирует эту конфигурацию?

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

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

Мы хотели, чтобы агентный сценарий был частью архитектуры платформы, а не автоматизацией поверх терминала. Поэтому MCP оперирует понятиями проекта, кода, секрета и статуса, а не внутренними сущностями Kubernetes.

Если совсем коротко, разница для нас выглядит так:

Классический PaaS автоматизирует выполнение деплоя. Мы пытаемся автоматизировать еще и его постановку.

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

Что мы поняли по дороге

Сначала мы думали, что строим удобную обертку над Kubernetes. На деле самым сложным оказался контракт между агентом и платформой.

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

Вторая важная вещь: магия хороша только снаружи. Внутри все должно оставаться скучным и воспроизводимым. Git хранит желаемое состояние. CI собирает неизменяемый образ. GitOps синхронизирует кластер. Vault хранит секреты. Backend проверяет права и связывает состояния. MCP дает агенту безопасный интерфейс ко всей этой машинерии.

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

И, наконец, полностью убрать человека пока нельзя. Агент способен найти процессы и переменные, но не всегда знает продуктовый контекст. Должен ли внутренний API быть публичным? Можно ли автоматически запустить миграцию? Какие реальные токены использовать для внешних интеграций? Иногда правильный следующий шаг для агента не вызвать инструмент, а задать владельцу проекта один хороший вопрос.

Для нас это не недостаток модели. Скорее нормальная граница: AI берет на себя механическую и исследовательскую часть, платформа гарантирует безопасное исполнение, а человек принимает решения, которые нельзя достоверно вывести из кода.

Равнобедренный треугольник ответственности
Равнобедренный треугольник ответственности

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

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

На этом месте инфраструктура внезапно становится самым медленным участником разговора.

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

До полной кнопки «сделай все красиво» еще далеко. Нужно улучшать диагностику сборок, откаты, логи, preview-окружения и способность агента исправлять собственные ошибки после деплоя.

Но базовый цикл уже выглядит именно так, как мы когда-то набросали на словах:

локальный код
    -> AI-агент анализирует проект
    -> MCP принимает ограниченные команды
    -> backend готовит Git, CI и инфраструктуру
    -> Kubernetes запускает приложение
    -> агент возвращает работающий HTTPS-адрес

И это, пожалуй, первый раз, когда фраза «ну попроси нейронку задеплоить» перестала звучать как шутка.