Сайт, который работает только у тебя на компьютере
У меня в какой-то момент накопилось несколько проектов, которые «работали». Написаны через Claude Code, крутятся на localhost, все кнопки нажимаются, база отвечает. Красота. Пока я не показал один из них знакомому — и тот спросил: «А где ссылка?»

И вот тут наступает момент истины, который знаком почти каждому начинающему вайб-кодеру. Ссылки нет. Сайт существует только на моей машине. localhost — это твой компьютер, обращающийся сам к себе. Ни у кого другого этого сайта нет, и не будет, пока ты не выложишь его в интернет.
Хорошая новость: путь «из папки на компьютере в интернет» — это не магия и не чёрный пояс по сетям. Это цепочка из четырёх понятных шагов: репозиторий → хостинг → домен → HTTPS. Я недавно прошёл её целиком на реальном проекте — платформе «Верный путь» — и расскажу, как она выглядит на практике. А заодно — про одну граблю, о которой молчат почти все туториалы: бывает, что ты всё сделал правильно, а сайт всё равно открывается не у всех.
Шаг 1. Репозиторий и хостинг: push = публикация
Первое, что нужно понять: хостингу не нужен твой компьютер. Код должен жить в репозитории — например, на GitHub. Это облачное хранилище кода с историей изменений.
Дальше подключаешь репозиторий к хостингу. Для Next.js-проектов стандартный выбор — Vercel: регистрируешься через GitHub-аккаунт, выбираешь репозиторий, жмёшь Deploy. Всё.
И вот что происходит дальше — самое приятное. Каждый раз, когда ты делаешь push в ветку main, Vercel сам забирает код, собирает проект и публикует его. Через пару минут новая версия сайта в интернете. Это и есть CI/CD на практике — continuous integration / continuous deployment, «непрерывная сборка и выкладка». Звучало страшно, оказалось — просто привычка «запушил = опубликовал».
Из этой привычки следует важное правило: сломал main — сломал прод. Если ты коммитишь недоделанную фичу прямо в main, она через пару минут окажется на живом сайте. Поэтому приучай себя сразу: что-то сырое — в отдельную ветку, Vercel для таких веток собирает превью-версии, посмотрел — и только потом сливаешь в main. В моём проекте добавился ещё один пункт дисциплины: после каждого пуша проверять деплой по конкретному новому URL, а не по главной странице — главная может выглядеть нормально, даже если новая страница не собралась.
Шаг 2. Секреты не живут в коде
Тут остановлюсь, потому что на этом спотыкаются часто и больно.
В твоём проекте наверняка есть ключи: подключение к базе данных, платёжный сервис, что-то ещё. Так вот, в коде и в репозитории им делать нечего. Публичный репозиторий с утёкшим ключом базы — это история про то, как кто-то делает покупки от твоего имени, а счёт приходит тебе.
Решение — переменные окружения (environment variables). Это, по сути, «заметки на холодильнике сервера»: ты кладёшь на хостинг пару «имя → значение», а код при запуске их читает. В Vercel они настраиваются в свойствах проекта, локально живут в файле .env.local, который не коммитится. В моём проекте так хранятся ключи базы и платёжного сервиса — и в коде их нет вообще.
Привычка простая: секреты — в переменные окружения, репозиторий — чистый. Всё.
Шаг 3. Домен — аренда имени, DNS — телефонная книга
Пока проект на Vercel, он доступен по техническому адресу вроде myproject.vercel.app. Работает, но выглядит несерьёзно и зависит от чужого домена. Хочется своё имя.
Тут важно понимать: домен ты не покупаешь навсегда, а арендуешь у регистратора. Я взял myrightway.ru на reg.ru — и, кстати, с 1 сентября 2026 года для зон .ru, .рф и .su обязательна идентификация владельца, я проходил её через Госуслуги. Заняло немного времени, но имей в виду.
Домен есть. Но как интернет узнаёт, куда вести человека, набравшего это имя? Для этого есть DNS — domain name system, «телефонная книга интернета». DNS переводит понятное человеку имя в IP-адрес — числовой адрес сервера. Ты вводишь myrightway.ru, браузер спрашивает у DNS «какой тут адрес», получает ответ и идёт по нему.
Заглянуть в эту телефонную книгу можно самому — командой nslookup (в Windows она есть из коробки). И тут первый сюрприз: вместо адреса моего хостинга я увидел IP вида 104.21.x.x и 172.67.x.x. Это общие диапазоны Cloudflare — сервиса, на который я делегировал DNS (перенёс управление NS-записями со своего регистратора). На одном таком IP «живут» тысячи сайтов. Это нормально — так устроен прокси Cloudflare: он стоит между посетителем и хостингом.
Сам переезд выглядел поэтапно: сначала сайт работал по адресу *.vercel.app, потом я прописал у регистратора записи, ведущие на Vercel (A-запись с адресом 216.198.79.1 и CNAME для www на cname.vercel-dns.com — это адреса, на которые «смотрит» домен), а уже потом перенёс NS на Cloudflare. Панели reg.ru, Cloudflare и Vercel регулярно меняют интерфейс, поэтому ищи настройки по смыслу: «управление DNS», «серверы имён», «добавить переменную».
И ещё одна вещь, о которой туториалы молчат: изменения в DNS доезжают не мгновенно. У каждой DNS-записи есть TTL — time to live, «время жизни». Это число секунд, в течение которых ответ о домене можно кешировать, то есть запоминать, всем узлам по пути. Пока TTL не истёк, никто не будет повторно спрашивать телефонную книгу — все ходят по старой памятке.
Поэтому после смены записей сайт у одних людей открывается по-новому, а у других ещё по-старому, и это не поломка. Я в первый переезд ждал «нажал кнопку — и сразу работает», а потом ловил себя на том, что проверяю домен, который у моего же провайдера ещё числится «старым». Правило простое: поменял DNS — подожди час-другой и проверяй повторно, а не через минуту.
Шаг 4. SSL — замок на двери, и он бесплатный
HTTPS — это когда соединение с сайтом зашифровано, а сайт подтверждает, что он действительно тот, за кого себя выдаёт. Свидетельство — SSL-сертификат.
Раньше сертификаты покупали и продлевали вручную. В 2026-м, если у тебя Vercel + Cloudflare, всё происходит само: сертификат выпускается автоматически и продлевается тоже. Я ни разу не покупал и не обновлял его руками.
Проверить, что замок работает, можно так:
curl -I https://твой-сайт.ru — увидишь ответ сервера: код, редиректы, заголовки. У меня это 200 OK.
curl -I http://твой-сайт.ru (без https) — сервер должен ответить 308 Permanent Redirect и отправить браузер на HTTPS. Держать открытый http «рядом» незачем.
Заголовок strict-transport-security (HSTS) — команда браузеру «на этот сайт всегда ходи только по HTTPS», даже если кто-то наберёт адрес без s.
Давай заодно разберём такой вывод построчно — новички часто смотрят на него как на заклинание. Реальный ответ моего сайта на curl -I выглядит примерно так:
HTTP/2 200
server: cloudflare
content-type: text/html; charset=utf-8
strict-transport-security: max-age=63072000HTTP/2 200 — версия протокола и код ответа. 200 — «всё хорошо, вот страница». HTTP/2 — современная версия HTTP, которая передаёт данные быстрее старой.
server: cloudflare — ответ пришёл не напрямую с хостинга, а через прокси Cloudflare, который стоит между посетителем и сервером.
content-type: text/html — тип содержимого: браузеру отдают HTML-страницу, а не картинку или файл.
strict-transport-security — тот самый HSTS, заголовок о том, что на сайт ходят только по HTTPS.
Никакой магии — сервер просто честно рассказывает о себе. Умение читать эти строки заменяет половину гаданий в духе «а почему сайт не работает».

Один нюанс: вывод curl зависит от твоей сети. «У меня 200 OK» не значит «у всех 200 OK» — и это подводит нас к самому интересному.
Когда сайт не открывается, а виноват не сайт
После настройки домена и SSL я столкнулся со странным: из России, без VPN, сайт открывался «лотереей». Часть запросов проходит, часть рвётся с ошибкой ERR_CONNECTION_RESET — соединение сброшено. Через VPN или с зарубежного IP — работает стабильно, ни одного сбоя.
Первая мысль у любого новичка: «Я что-то сломал». Спойлер: нет.

Разбор на пальцах. Cloudflare выдаёт сайту IP из общего диапазона, где соседей — тысячи. А внутри TLS-рукопожатия (первого «здравствуйте» браузера и сервера) имя сайта — оно называется SNI — передаётся открытым текстом, чтобы сервер понимал, какой сертификат показать. Оборудование провайдеров (так называемый DPI — deep packet inspection, глубокий анализ трафика) видит это имя и может рвать соединение. Отсюда и поведение: не бан конкретного сайта, а массовые сбои на общих диапазонах — где-то пропустили, где-то оборвали.
У меня есть почти лабораторное доказательство. Эксперимент с одного и того же рабочего IP: запрос, где в рукопожатии фигурировал vercel.app, проходил мгновенно. Запрос с тем же IP, но с именем myrightway.ru — зависал. Меняется только имя домена в SNI, всё остальное то же самое — и результат разный. Значит, фильтруют по имени, а не по IP и не по содержимому сайта.
Позже был и второй эпизод, поучительный в другую сторону. Один из пользователей прислал скрин: DevTools (инструменты разработчика в браузере) показывал ERR_CONNECTION_CLOSED на части ресурсов. Разобрались — у него на компьютере стоял VPN, и рвал соединения он. С других машин тот же сайт отвечал 200 по всем адресам.
Тут стоит рассказать, что вообще показывает DevTools в такой ситуации. Открываешь панель клавишей F12, вкладка Network («сеть»), обновляешь страницу — и видишь список всех запросов, из которых складывается страница: сам HTML, скрипты, стили, картинки, шрифты. Каждый запрос — строка со статусом. Строка со статусом 200 — дошло. Красная строка с пометкой failed («не удался») — не дошло. Наведёшься на неё — увидишь текст ошибки.
Разные ошибки говорят о разном. ERR_CONNECTION_RESET — соединение активно сброшено: именно так выглядит RST от фильтра на пути к сайту. ERR_CONNECTION_CLOSED — соединение закрыли, не дав ответа: похоже, но чуть «вежливее». И самое важное — смотреть, что именно не загрузилось. В том скрине HTML открывался, а часть субресурсов — скриптов и картинок — отваливалась. Подумай, что это значит: если бы я сломал сборку сайта, отвалилось бы всё и у всех. А когда у одного человека падает часть запросов, а с других машин всё отвечает 200 — почти всегда виновата его сеть, а не твой код.
Отдельно честно про Cloudflare. Когда я включил его прокси, доступность из РФ сразу заметно выросла: пять запросов из пяти — около секунды, валидный SSL. Но по свежим замерам картинка снова «плавает» — плавающие ERR_CONNECTION_RESET вернулись. Это смягчение проблемы, а не гарантия: поведение меняется со временем и зависит от провайдера. Альтернативы вроде своего сервера в России или другого CDN существуют, но это уже отдельная история — здесь я про основы, а не про обход блокировок.
Чек-лист: «сайт не открывается — кто виноват?»
Эта диагностика — скилл на всю жизнь. Порядок такой:
nslookup твой-домен.ru — резолвится ли имя вообще? Если DNS не отвечает, дальше можно не смотреть: проблема с именем или у твоего провайдера.
curl -I https://твой-домен.ru — что говорит сам сервер? Код 200, редирект 308, заголовки — это здоровый ответ. Если сервер отвечает, значит сайт жив.
Проверка с другого IP — VPN или зарубежный сервер. Если там 200, а у тебя RST — проблема в сети между тобой и сайтом, а не в твоём коде.
Телефон в мобильной сети — выключи Wi-Fi и открой сайт с телефона через мобильный интернет. Мобильный оператор — это другой провайдер с другим фильтром. Если с телефона открывается, а с домашнего Wi-Fi нет (или наоборот) — виноват конкретный провайдер, не сайт.
DevTools, вкладка Network — что именно не загрузилось: всё подряд или только часть запросов? Всё и у всех — похоже на твой баг. Часть запросов и только у одного человека — почти наверняка его сеть.
Именно так в нашем случае и сложилась картина: 200 OK по HTTPS, 308 с http, через VPN — стабильно, на разных провайдерах — разные результаты. Вывод: сайт исправен, рвёт дорога. Паника «я сломал прод» снята за десять минут.
Маленький словарик
Все термины из статьи — по одной строке, чтобы было куда вернуться:
Деплой — выкладка проекта с твоего компьютера на хостинг, чтобы он стал доступен в интернете.
Репозиторий — облачное хранилище кода с историей изменений, например на GitHub.
DNS — «телефонная книга интернета»: переводит понятное имя сайта в IP-адрес сервера.
SNI — имя сайта, которое браузер называет в открытом виде в начале шифрованного соединения, чтобы сервер понял, какой сертификат показать.
DPI — оборудование провайдера, которое просматривает проходящий трафик и может рвать соединения по имени или адресу.
HSTS — заголовок от сайта браузеру: «на этот сайт ходи только по HTTPS, и никак иначе».
Что это значит на практике
localhost ≠ интернет. Пока код только у тебя, сайта «в интернете» не существует. Цепочка деплоя: репозиторий → хостинг → домен → HTTPS.
Подключи GitHub к Vercel один раз — дальше push в main = публикация. Сырое — в ветку, превью, потом merge. Секреты — в переменные окружения на хостинге, не в коде.
Домен — аренда имени у регистратора, DNS — телефонная книга, переводящая имя в адрес. SSL в связке Cloudflare + Vercel ставится и продлевается сам.
«Сайт не открывается» — не всегда твой баг. Три команды (nslookup, curl -I, проверка с другого IP) отделяют «я сломал» от «рвёт провайдерский DPI».
Честный итог
Деплой — самая простая часть всего пути. Сборка на Vercel занимает минуты, SSL автоматический, домен покупается за полчаса. Самое сложное начинается после — когда выясняется, что для пользователей из твоей страны доступность зависит не от тебя. К этому стоит быть готовым морально и — что важнее — уметь отличать свои баги от сетевых. Чек-лист из этой статьи как раз про это. Сохрани его: в тот вечер, когда «сайт не открывается», ты скажешь себе спасибо.


