<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Блог Layero</title>
        <link>https://docs.layero.ru/en/blog</link>
        <description>Layero Docs Blog</description>
        <lastBuildDate>Wed, 13 May 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>© 2026 Layero</copyright>
        <item>
            <title><![CDATA[Как мы строили «Vercel для России»: четыре переписывания билда и другие приключения]]></title>
            <link>https://docs.layero.ru/en/blog/what-is-layero</link>
            <guid>https://docs.layero.ru/en/blog/what-is-layero</guid>
            <pubDate>Wed, 13 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[История создания Layero — платформы деплоя фронтенда для российских разработчиков. От первой версии, которая просто раздавала статику, до gVisor-воркеров, автодетекта восьми фреймворков и превью за 30 секунд.]]></description>
            <content:encoded><![CDATA[<p>Знакомый прислал ссылку на лендинг своего стартапа. Сайт не открывался без VPN.</p>
<p>Я спросил, где деплоил. Vercel, говорит. Ну да, говорю, понятно.</p>
<p>За последние пару лет это стало паттерном. Разработчик делает сайт, деплоит на Vercel — потому что это удобно и быстро — а потом обнаруживает, что половина его российской аудитории видит либо тайм-аут, либо страницу браузера с предложением проверить соединение. AWS-регионы, на которых работает Vercel, работают для России нестабильно — зависит от провайдера, региона и фазы луны.</p>
<!-- -->
<p>Окей, есть же Yandex Cloud. Российская инфраструктура, рублёвый биллинг, стабильные IP. Но поднять там статический сайт с HTTPS и доменом — это несколько часов в консоли, три разных сервиса и неизбежный ритуал с DNS-чейленджем, который с первого раза не работает. Я проходил этот квест несколько раз и каждый раз тихо матерился в районе Certificate Manager.</p>
<p>В какой-то момент стало понятно, что это системная дыра. Современный вайбкодер — человек, который написал сайт в Cursor или собрал лендинг через Bolt — не должен знать ничего про DNS-записи для подтверждения сертификатов. Он должен нажать кнопку и получить живой сайт. Именно это мы и строим.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="что-такое-layero">Что такое Layero<a href="https://docs.layero.ru/en/blog/what-is-layero#%D1%87%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-layero" class="hash-link" aria-label="Direct link to Что такое Layero" title="Direct link to Что такое Layero" translate="no">​</a></h2>
<p>Одна строчка: платформа деплоя фронтенда на российской инфраструктуре.</p>
<p>Даёшь репозиторий — получаешь живой сайт с доменом, HTTPS и превью-средой для каждой ветки. Сертификаты, CDN, сборка — наша забота. Рублёвый биллинг, никакого Stripe.</p>
<p>Ключевая вещь — превью-среды. Каждый push в ветку получает свой URL, доступный через 30 секунд после сборки. Пул-реквест можно показать дизайнеру прямо из гитхаба, не объясняя, как запустить проект локально.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="как-устроен-деплой-под-капотом">Как устроен деплой под капотом<a href="https://docs.layero.ru/en/blog/what-is-layero#%D0%BA%D0%B0%D0%BA-%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD-%D0%B4%D0%B5%D0%BF%D0%BB%D0%BE%D0%B9-%D0%BF%D0%BE%D0%B4-%D0%BA%D0%B0%D0%BF%D0%BE%D1%82%D0%BE%D0%BC" class="hash-link" aria-label="Direct link to Как устроен деплой под капотом" title="Direct link to Как устроен деплой под капотом" translate="no">​</a></h2>
<p>Когда приходит webhook от GitHub, API сразу возвращает ответ и уходит — сборка запускается асинхронно в отдельном воркере. Воркер клонирует репозиторий, определяет фреймворк, ставит зависимости, собирает проект, загружает результат в S3 и активирует деплой. После активации все узлы платформы узнают о новом контенте в течение примерно 10 секунд — через механизм уведомлений в базе данных.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="превью-за-30-секунд-при-15-минутном-cdn">Превью за 30 секунд при 15-минутном CDN<a href="https://docs.layero.ru/en/blog/what-is-layero#%D0%BF%D1%80%D0%B5%D0%B2%D1%8C%D1%8E-%D0%B7%D0%B0-30-%D1%81%D0%B5%D0%BA%D1%83%D0%BD%D0%B4-%D0%BF%D1%80%D0%B8-15-%D0%BC%D0%B8%D0%BD%D1%83%D1%82%D0%BD%D0%BE%D0%BC-cdn" class="hash-link" aria-label="Direct link to Превью за 30 секунд при 15-минутном CDN" title="Direct link to Превью за 30 секунд при 15-минутном CDN" translate="no">​</a></h3>
<p>YC CDN распространяется по регионам 5–15 минут. Это объективная реальность, которую не обойти. При этом хочется, чтобы превью была доступна сразу после сборки — иначе какой смысл.</p>
<p>Решение: два отдельных пути доставки для каждого деплоя.</p>
<p>Первый путь — превью-ссылка, которая идёт напрямую с сервера, минуя CDN. Сайт живёт через 30 секунд после завершения сборки.</p>
<p>Второй путь — основной адрес проекта через CDN: нормальный TLS, кеширование на краевых узлах, глобальная доступность. Готовность CDN определяем инструментально — опрашиваем несколько публичных DNS-резолверов и ждём, пока регион не прогреется. Как только это произошло, превью-ссылка автоматически начинает перенаправлять на основной адрес. Через сутки превью перестаёт работать.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="spa-fallback-то-чего-yc-cdn-не-умеет">SPA fallback: то, чего YC CDN не умеет<a href="https://docs.layero.ru/en/blog/what-is-layero#spa-fallback-%D1%82%D0%BE-%D1%87%D0%B5%D0%B3%D0%BE-yc-cdn-%D0%BD%D0%B5-%D1%83%D0%BC%D0%B5%D0%B5%D1%82" class="hash-link" aria-label="Direct link to SPA fallback: то, чего YC CDN не умеет" title="Direct link to SPA fallback: то, чего YC CDN не умеет" translate="no">​</a></h3>
<p>Классическая проблема SPA: пользователь открывает <code>https://example.com/dashboard</code> напрямую — CDN смотрит в S3, файла <code>/dashboard</code> нет, возвращает 404. Нужен fallback: на 404 отдавать <code>index.html</code> с кодом 200.</p>
<p>Vercel делает это из коробки. YC CDN — нет, просто не поддерживает. Поэтому между CDN и хранилищем у нас стоит дополнительный слой, который перехватывает 404 и отдаёт <code>index.html</code>. Это стандартная схема для SPA, но её пришлось явно организовать самостоятельно.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="изоляция-сборок-gvisor">Изоляция сборок: gVisor<a href="https://docs.layero.ru/en/blog/what-is-layero#%D0%B8%D0%B7%D0%BE%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D1%81%D0%B1%D0%BE%D1%80%D0%BE%D0%BA-gvisor" class="hash-link" aria-label="Direct link to Изоляция сборок: gVisor" title="Direct link to Изоляция сборок: gVisor" translate="no">​</a></h3>
<p>Сборки пользователей — это чужой код, которому доверять нельзя. Запускать его напрямую на сервере — плохая идея.</p>
<p>Для изоляции используем <a href="https://gvisor.dev/" target="_blank" rel="noopener noreferrer" class="">gVisor</a>. Это не полноценная виртуальная машина, но гораздо лучше обычного Docker: gVisor перехватывает системные вызовы и исполняет их в изолированной среде, не давая коду добраться до хостовой системы. Дешевле полноценной виртуализации, но достаточно для наших целей.</p>
<p>Каждый воркер работает с ограниченной памятью и процессором, без доступа к файловой системе хоста и с выходом в сеть только на нужные адреса — npm-registry, GitHub, наше хранилище. Раз в несколько минут фоновый процесс убирает завершившиеся контейнеры и временные файлы.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="четыре-переписывания-архитектуры-билда">Четыре переписывания архитектуры билда<a href="https://docs.layero.ru/en/blog/what-is-layero#%D1%87%D0%B5%D1%82%D1%8B%D1%80%D0%B5-%D0%BF%D0%B5%D1%80%D0%B5%D0%BF%D0%B8%D1%81%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D0%B0%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D1%8B-%D0%B1%D0%B8%D0%BB%D0%B4%D0%B0" class="hash-link" aria-label="Direct link to Четыре переписывания архитектуры билда" title="Direct link to Четыре переписывания архитектуры билда" translate="no">​</a></h2>
<p>Это та часть истории, которую стоит рассказать подробно.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="попытка-первая-serverless-container">Попытка первая: Serverless Container<a href="https://docs.layero.ru/en/blog/what-is-layero#%D0%BF%D0%BE%D0%BF%D1%8B%D1%82%D0%BA%D0%B0-%D0%BF%D0%B5%D1%80%D0%B2%D0%B0%D1%8F-serverless-container" class="hash-link" aria-label="Direct link to Попытка первая: Serverless Container" title="Direct link to Попытка первая: Serverless Container" translate="no">​</a></h3>
<p>Очевидная первая мысль — запускать сборки в YC Serverless Container. Serverless масштабируется сам, платишь за использование, не надо думать об инфраструктуре. Звучит хорошо.</p>
<p>YC Serverless Container даёт 256 МБ временного места на диске — и всё. Кэш пакетного менеджера писать некуда. Крупный проект с 300+ зависимостями переполняет этот лимит ещё на этапе установки. Первое время мы говорили пользователям, что у них «слишком большой проект» — что, конечно, было неправдой.</p>
<p>С сетью отдельная история. Serverless NAT сбрасывает неактивные соединения примерно через две минуты. Установка пакетов — это сотни последовательных запросов к registry, каждый из которых может попасть в это окно. Результат: установка зависала на середине без каких-либо ошибок в логах, просто переставала что-либо делать. Целые сборки уходили в тайм-аут по 16 минут.</p>
<p>Итого: 15+ минут на CRA-проект, нестабильность, и отсутствие кэша означало, что каждый деплой скачивал все зависимости заново.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="попытки-вторая-и-третья-борьба-с-ограничениями">Попытки вторая и третья: борьба с ограничениями<a href="https://docs.layero.ru/en/blog/what-is-layero#%D0%BF%D0%BE%D0%BF%D1%8B%D1%82%D0%BA%D0%B8-%D0%B2%D1%82%D0%BE%D1%80%D0%B0%D1%8F-%D0%B8-%D1%82%D1%80%D0%B5%D1%82%D1%8C%D1%8F-%D0%B1%D0%BE%D1%80%D1%8C%D0%B1%D0%B0-%D1%81-%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8" class="hash-link" aria-label="Direct link to Попытки вторая и третья: борьба с ограничениями" title="Direct link to Попытки вторая и третья: борьба с ограничениями" translate="no">​</a></h3>
<p>Следующие два захода — вариации на тему «обойти ограничения не меняя архитектуру». Указывали пакетным менеджерам альтернативные пути для кэша, скачивали исходники через архивный API GitHub вместо полноценного git-клонирования — это быстрее и не страдает от NAT. Помогало, но не кардинально. 15 минут превратились в 8–10, но системные проблемы никуда не делись.</p>
<p>Параллельно несколько недель теряли время на охоту за случайными зависаниями при установке пакетов. Симптомы выглядели как «что-то с сетью YC». Оказалось — собственный npm-прокси, который мы подняли для кэширования. При одновременных запросах к внешнему registry он уходил в offline-режим, и менеджер пакетов вместо ошибки просто висел в ожидании ответа, который никогда не придёт. Фиксится одним параметром конфигурации — но чтобы это найти, нужно было несколько итераций с включёнными подробными логами.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="попытка-четвёртая-vm-с-nvme">Попытка четвёртая: VM с NVMe<a href="https://docs.layero.ru/en/blog/what-is-layero#%D0%BF%D0%BE%D0%BF%D1%8B%D1%82%D0%BA%D0%B0-%D1%87%D0%B5%D1%82%D0%B2%D1%91%D1%80%D1%82%D0%B0%D1%8F-vm-%D1%81-nvme" class="hash-link" aria-label="Direct link to Попытка четвёртая: VM с NVMe" title="Direct link to Попытка четвёртая: VM с NVMe" translate="no">​</a></h3>
<p>Решение, которое реально сработало — перестать бороться с ограничениями SC и просто взять нормальную VM с NVMe-диском.</p>
<p>На VM работает диспетчер, который принимает задачи сборки и поднимает под каждую изолированный контейнер. Кэш зависимостей хранится на хосте и доступен контейнеру — так пакеты не скачиваются заново при каждом деплое.</p>
<p>Время сборки — 2–3 минуты на типичном проекте. Сеть стабильная. Диск не заканчивается.</p>
<p>Сейчас работаем над пятым заходом: параллельные сборки и умная очистка кэша зависимостей. Но это уже оптимизация поверх работающей системы, а не попытка реанимировать то, что работать не хочет.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="что-такое-проект-окружение-и-деплой">Что такое проект, окружение и деплой<a href="https://docs.layero.ru/en/blog/what-is-layero#%D1%87%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82-%D0%BE%D0%BA%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B8-%D0%B4%D0%B5%D0%BF%D0%BB%D0%BE%D0%B9" class="hash-link" aria-label="Direct link to Что такое проект, окружение и деплой" title="Direct link to Что такое проект, окружение и деплой" translate="no">​</a></h2>
<p>Этот вопрос кажется тривиальным ровно до того момента, как начинаешь реализовывать.</p>
<p>У нас три уровня: проект, окружение, деплой. Проект — это репозиторий. Окружение — это ветка: основная ветка становится продакшном, любая другая — превью. У каждого окружения свой адрес и указатель на текущую живую сборку. Если сборка упала, мы фиксируем, на каком именно шаге — клонирование, установка зависимостей, компиляция, загрузка — чтобы в логах можно было сразу понять, куда смотреть.</p>
<p>В первой версии слоя «окружений» не существовало — проект напрямую ссылался на деплои. Это работало ровно до появления превью-сред, когда стало непонятно, что считать продакшном, а что — временным превью.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="автодетект-фреймворка">Автодетект фреймворка<a href="https://docs.layero.ru/en/blog/what-is-layero#%D0%B0%D0%B2%D1%82%D0%BE%D0%B4%D0%B5%D1%82%D0%B5%D0%BA%D1%82-%D1%84%D1%80%D0%B5%D0%B9%D0%BC%D0%B2%D0%BE%D1%80%D0%BA%D0%B0" class="hash-link" aria-label="Direct link to Автодетект фреймворка" title="Direct link to Автодетект фреймворка" translate="no">​</a></h2>
<p>Загружаешь репозиторий — платформа сама понимает, что перед ней: Next.js, Vite, Astro, Nuxt, SvelteKit, Gatsby, CRA, Docusaurus или просто статические файлы. Определяет пакетный менеджер по lock-файлу, подбирает версию Node.js из конфига проекта. Поддерживаются Node 18, 20 и 22 — бинарники предустановлены в образе, ничего не скачивается в процессе сборки.</p>
<p>Любое из этих решений можно переопределить вручную в настройках проекта или при деплое через CLI.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="сертификаты">Сертификаты<a href="https://docs.layero.ru/en/blog/what-is-layero#%D1%81%D0%B5%D1%80%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D1%8B" class="hash-link" aria-label="Direct link to Сертификаты" title="Direct link to Сертификаты" translate="no">​</a></h2>
<p>Именно с этим начинался весь проект.</p>
<p>В Layero SSL работает так: добавляешь домен — платформа сама запрашивает сертификат через Let's Encrypt и прикрепляет к CDN. Если что-то пошло не так — показываем причину. Предупреждаем за две недели до истечения.</p>
<p>Пользователь видит «Сертификат выдаётся», потом «Активен». Слова «DNS-01» нигде нет.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="стек">Стек<a href="https://docs.layero.ru/en/blog/what-is-layero#%D1%81%D1%82%D0%B5%D0%BA" class="hash-link" aria-label="Direct link to Стек" title="Direct link to Стек" translate="no">​</a></h2>
<p>Бэкенд — Python, FastAPI, PostgreSQL. SQL пишем руками без ORM — это сознательное решение: понимаешь, что именно происходит и почему тормозит. Билдер на том же стеке. CLI — TypeScript, 4 зависимости, никакого bloat. Фронтенд контрол-плейна — React + Vite + Tailwind — деплоится через Layero.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="где-мы-сейчас">Где мы сейчас<a href="https://docs.layero.ru/en/blog/what-is-layero#%D0%B3%D0%B4%D0%B5-%D0%BC%D1%8B-%D1%81%D0%B5%D0%B9%D1%87%D0%B0%D1%81" class="hash-link" aria-label="Direct link to Где мы сейчас" title="Direct link to Где мы сейчас" translate="no">​</a></h2>
<p>Платформа работает. Деплои идут, сертификаты выдаются, превью появляются за 30 секунд. CLI умеет одной командой задеплоить локальную папку и проходит логин по device-flow — токен забирается из браузера через бэкенд, без локального HTTP-сервера, поэтому работает даже из песочниц AI-агентов (Cursor, Claude Code). В работе: параллельные сборки и поддержка серверного рендеринга (Next.js, SvelteKit с серверной частью).</p>
<p>Если есть проект, который нужно задеплоить в России, — попробуйте: <a href="https://app.layero.ru/" target="_blank" rel="noopener noreferrer" class="">app.layero.ru</a></p>]]></content:encoded>
            <category>Анонс</category>
        </item>
        <item>
            <title><![CDATA[Привет, Layero!]]></title>
            <link>https://docs.layero.ru/en/blog/hello-layero</link>
            <guid>https://docs.layero.ru/en/blog/hello-layero</guid>
            <pubDate>Sat, 02 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Первый пост в блоге Layero. Что мы будем публиковать здесь и как подписаться.]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" alt="Привет, Layero!" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDYwMCIgd2lkdGg9IjEyMDAiIGhlaWdodD0iNjAwIj4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0iYmciIHgxPSIwIiB5MT0iMCIgeDI9IjEiIHkyPSIxIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmFmOWY1Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2Y0ZGNjZCIvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICA8L2RlZnM+CiAgPHJlY3Qgd2lkdGg9IjEyMDAiIGhlaWdodD0iNjAwIiBmaWxsPSJ1cmwoI2JnKSIvPgogIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMCAxODApIj4KICAgIDxyZWN0IHdpZHRoPSIxNjAiIGhlaWdodD0iMTYwIiByeD0iMzIiIGZpbGw9IiMxNDE0MTMiLz4KICAgIDx0ZXh0IHg9IjgwIiB5PSIxMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiCiAgICAgICAgICBmb250LWZhbWlseT0iSW50ZXIsIC1hcHBsZS1zeXN0ZW0sIHNhbnMtc2VyaWYiCiAgICAgICAgICBmb250LXdlaWdodD0iOTAwIiBmb250LXN0eWxlPSJpdGFsaWMiIGZvbnQtc2l6ZT0iMTE4IgogICAgICAgICAgZmlsbD0iI2ZmZmZmZiIgbGV0dGVyLXNwYWNpbmc9Ii0zIj5MPC90ZXh0PgogIDwvZz4KICA8dGV4dCB4PSIzMjAiIHk9IjI4MCIgZm9udC1mYW1pbHk9IkludGVyLCAtYXBwbGUtc3lzdGVtLCBzYW5zLXNlcmlmIgogICAgICAgIGZvbnQtd2VpZ2h0PSI2MDAiIGZvbnQtc2l6ZT0iNjgiIGZpbGw9IiMxNDE0MTMiIGxldHRlci1zcGFjaW5nPSItMiI+CiAgICDQn9GA0LjQstC10YIsIExheWVybyEKICA8L3RleHQ+CiAgPHRleHQgeD0iMzIwIiB5PSIzNDAiIGZvbnQtZmFtaWx5PSJJbnRlciwgLWFwcGxlLXN5c3RlbSwgc2Fucy1zZXJpZiIKICAgICAgICBmb250LXdlaWdodD0iNDAwIiBmb250LXNpemU9IjI4IiBmaWxsPSIjNzM3MjZjIj4KICAgINCl0L7RgdGC0LjQvdCzINC00LvRjyDRhNGA0L7QvdGC0LXQvdC00LAuINCh0LXRgNCy0LXRgNGLINCyINCg0L7RgdGB0LjQuC4KICA8L3RleHQ+CiAgPHRleHQgeD0iMzIwIiB5PSI0NzUiIGZvbnQtZmFtaWx5PSJKZXRCcmFpbnMgTW9ubywgbW9ub3NwYWNlIgogICAgICAgIGZvbnQtd2VpZ2h0PSI1MDAiIGZvbnQtc2l6ZT0iMjIiIGZpbGw9IiNkOTc3NTciPgogICAgJCBsYXllcm8gZGVwbG95CiAgPC90ZXh0Pgo8L3N2Zz4K" width="1200" height="600" class="img_ev3q"></p>
<p>Это первый пост в блоге Layero. Здесь мы будем публиковать новости
платформы, релизы CLI и заметки команды о том, как устроена платформа
изнутри.</p>
<!-- -->
<p>Подписаться можно через RSS — ссылка в подвале блога.</p>]]></content:encoded>
            <category>Анонс</category>
        </item>
    </channel>
</rss>