JavaRush /Курсы /ChatGPT Apps /Локальный запуск, HTTPS‑туннель и доступность для ChatGPT...

Локальный запуск, HTTPS‑туннель и доступность для ChatGPT

ChatGPT Apps
2 уровень , 2 лекция
Открыта

1. localhost — это только для вас, а не для ChatGPT

Начнём с главного когнитивного диссонанса этого модуля. Вы открываете http://localhost:3000 в браузере, всё прекрасно работает, Next.js улыбается, виджет рендерится. Кажется логичным: «Ну раз у меня есть URL, давайте просто дадим его ChatGPT».

Проблема в том, что localhost — это не «магический домен моей машины в интернете». Это особое имя, которое всегда указывает на ту же машину, где запущен браузер или клиент. Ваш ноутбук обращается к самому себе. Серверы OpenAI, где крутится ChatGPT, тоже умеют обращаться к localhost… но к своему — внутри датацентра. А ваш Next.js счастливо спрятан за домашним роутером, NAT и, возможно, корпоративным VPN.

В этой лекции мы:

  • разберёмся, почему localhost недоступен для ChatGPT;
  • настроим HTTPS‑туннель через cloudflared от localhost:3000 до публичного URL;
  • подключим этот URL в ChatGPT Dev Mode;
  • проверим цепочку «код → туннель → ChatGPT» на простом изменении в виджете и обсудим типичные грабли.

Из этого вытекает два простых факта:

  1. ChatGPT не знает, где находится ваш ноутбук.
  2. Даже если бы знал, напрямую постучаться к нему он тоже не может — входящие соединения закрыты.

Кроме того, ChatGPT принципиально работает только с публичными HTTPS‑эндпоинтами (точками входа): нужен нормальный домен и TLS‑сертификат. Серверы OpenAI по соображениям безопасности не ходят на произвольные HTTP‑адреса без шифрования, поэтому нужен именно HTTPS‑домен с валидным сертификатом. Просто пробросить наружу http://мой‑внешний‑IP:3000 — уже не вариант.

Поэтому нам нужен посредник — сервис, который:

  1. Живёт в интернете с нормальным HTTPS‑доменом.
  2. Может безопасно пробросить запросы с этого домена к вашему localhost:3000.

Это и есть HTTPS‑туннель.

2. Что такое HTTPS‑туннель: интуитивная модель

Если отбросить все страшные слова, туннель — это сервис, который даёт вам временный (или постоянный) публичный URL и пересылает все запросы оттуда на ваш локальный порт. В сетевой терминологии это, по сути, обратный прокси‑сервер (reverse‑прокси), который держит исходящее соединение к облаку.

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

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

sequenceDiagram
    participant ChatGPT as ChatGPT (облако)
    participant Tunnel as HTTPS‑туннель
(Cloudflare / ngrok) participant Dev as Ваш dev‑сервер
(localhost:3000) ChatGPT->>Tunnel: HTTPS запрос к https://xyz.trycloudflare.com Tunnel->>Dev: HTTP запрос к http://localhost:3000 Dev-->>Tunnel: Ответ Next.js Tunnel-->>ChatGPT: HTTPS ответ

Ключевые моменты здесь такие.

Во‑первых, инициатором соединения с туннельным сервисом являетесь вы. Утилита (cloudflared, ngrok и т.п.) сама устанавливает исходящее соединение к облаку. Это почти всегда разрешено даже за NAT/файрволлом.

Во‑вторых, туннельный сервис выдаёт вам HTTPS‑домен с валидным сертификатом, так что никакой самоподписанный TLS руками поднимать не нужно.

В‑третьих, для ChatGPT ваш App выглядит как обычный веб‑сервис с HTTPS‑доменом. Он не подозревает, что дальше трафик уходит к кому‑то на ноутбук.

3. Какие бывают туннели и что мы выберем в курсе

В экосистеме веб‑разработки есть несколько популярных решений для такой задачи:

  • ngrok — классика жанра, очень долго был де‑факто стандартом «как показать локалку наружу».
  • Cloudflare Tunnel (cloudflared) — современное бесплатное решение от Cloudflare, даёт домен вида *.trycloudflare.com даже без регистрации; можно прикрепить и свой домен при желании.
  • LocalTunnel — минимум магии, просто npm‑пакет, который выдаёт временный HTTPS‑URL вроде https://something.loca.lt.

Все они решают одну и ту же задачу: дать локальному серверу публичный HTTPS‑домен, который подходит ChatGPT.

Для курса нам важно не распылять внимание, поэтому в качестве «основного» инструмента мы возьмём Cloudflare Tunnel с утилитой cloudflared. Причины простые: не требует регистрации для быстрых туннелей, даёт нормальный HTTPS, легко запускается одной командой.

При этом, если вы уже фанат ngrok — ничего страшного. Команды будут чуть другими, но концепция один в один: ngrok http 3000 вместо cloudflared tunnel --url http://localhost:3000.

Чтобы было проще ориентироваться, сведём инструменты в небольшую таблицу.

Инструмент Нужна регистрация? Формат URL Главные плюсы Главные минусы
Cloudflare Tunnel Нет
https://*.trycloudflare.com
Быстрый старт, валидный HTTPS URL меняется при каждом запуске
ngrok Да
https://*.ngrok.app
Огромная документация, экосистема Бесплатный URL тоже меняется
LocalTunnel Нет
https://*.loca.lt
npm‑установка, минимум магии Нестабильные домены, меньше фичей

В этой лекции мы сосредоточимся на Cloudflare Tunnel в режиме «быстрый одноразовый туннель». Этого более чем достаточно, чтобы «подружить» ваш Next.js с ChatGPT в Dev Mode.

4. Проверяем, что локальный Next.js жив

Прежде чем тянуть наружу что‑то через туннель, нужно убедиться, что локальный сервер реально работает. Иначе вы будете отлаживать туннель, хотя проблема в том, что Next.js просто не запущен.

Напомню стандартный порядок:

# из корня проекта с шаблоном Apps SDK
npm install      # если ещё не делали
npm run dev      # запуск dev-сервера Next.js

По умолчанию Next.js 16 поднимется на http://localhost:3000 (если порт не занят). В терминале вы увидите что‑то вроде:

ready - started server on 0.0.0.0:3000, url: http://localhost:3000

Откройте в браузере http://localhost:3000 и убедитесь, что страница шаблона открывается. Это ваша «локальная лаборатория». Если здесь что‑то не работает (ошибка сборки, TypeScript ругается, порт занят) — сначала чините это, потом переходите к туннелю.

5. Запускаем Cloudflare Tunnel: от localhost к публичному HTTPS

Переходим к самому вкусному — делаем так, чтобы кто‑угодно в интернете (включая ChatGPT) мог открыть ваш Next.js по HTTPS‑URL.

Установка cloudflared

Способ установки зависит от ОС. Самый простой путь для macOS — через Homebrew:

brew install cloudflare/cloudflare/cloudflared

На Windows и Linux можно скачать готовый бинарник или использовать менеджер пакетов, как рекомендует документация Cloudflare (ссылки есть в дополнительных материалах модуля).

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

cloudflared --version

Если утилита не нашлась, проверьте PATH или перезапустите терминал.

Быстрый одноразовый туннель

Наша цель сейчас — минимальный рабочий туннель, без аккаунта, домена и сложных конфигов. Для этого у cloudflared есть режим quick tunnel, который даёт URL на домене trycloudflare.com.

При запущенном npm run dev выполните в другом терминале:

cloudflared tunnel --url http://localhost:3000

Запомните простое правило: HTTPS — снаружи, HTTP — внутрь. cloudflared сам выдаёт вам снаружи HTTPS‑домен, но до вашего localhost:3000 он ходит по обычному HTTP.

После короткого лога вы увидите строку вроде:

INF +-------------------------------------------------------------+
INF |  Your quick Tunnel has been created!                        |
INF |  https://giftgenius-1234.trycloudflare.com                  |
INF +-------------------------------------------------------------+

Этот https://giftgenius-1234.trycloudflare.com — и есть новый публичный адрес вашего локального приложения. Туннель принимает HTTPS‑запросы на этот домен и пересылает их на http://localhost:3000.

Пара важных моментов.

Во‑первых, терминал с cloudflared должен оставаться открытым, пока туннель нужен. Как только вы его закроете (или нажмёте Ctrl+C), туннель падает, URL перестаёт работать.

Во‑вторых, при каждом запуске quick tunnel URL может быть новым. Для нашей учебной разработки это нормально: цель текущего модуля — просто дать ChatGPT доступ к вашему локальному Next.js через любой рабочий HTTPS‑адрес. Но это значит, что в ChatGPT Dev Mode иногда придётся обновлять URL. В модуле 7 мы вернёмся к теме туннелей и настроим уже полноценный стабильный dev‑домен, чтобы не бегать за адресами.

Проверяем туннель как обычный сайт

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

  1. Откройте полученный https://...trycloudflare.com в браузере.
  2. Вы должны увидеть тот же UI, что и на http://localhost:3000.
  3. В консоли, где крутится npm run dev, вы увидите новые запросы — то есть Next.js действительно обслуживает внешнее обращение.

Если страница не открывается или там ошибка, сначала проверьте:

  • Запущен ли npm run dev.
  • Не ошиблись ли вы в локальном URL при запуске туннеля (http://localhost:3000, а не https:// и не порт 3001).
  • Не блокирует ли что‑то исходящие соединения (редко, но бывает в строгих корпоративных сетях).

6. Прокидываем этот URL в ChatGPT Dev Mode

Теперь у нас есть всё, чтобы связать цепочку:

ChatGPT (облако) → ваш HTTPS‑туннель → локальный Next.js.

Часть про интерфейс Dev Mode вы уже видели в предыдущей лекции, сейчас просто повторим то же самое, но с реальным HTTPS‑URLом, а не теоретическим.

Общая последовательность действий в ChatGPT такая.

Сначала откройте ChatGPT в браузере и перейдите в раздел для разработчиков (обычно что‑то вроде «Developer», «Apps», «My apps» — конкретные названия могут меняться с обновлением UI).

Создайте новое приложение или отредактируйте уже существующее dev‑приложение, если вы его уже создовали.

В поле, куда требуется вставить URL вашего App, укажите корневой адрес туннеля, например:

https://giftgenius-1234.trycloudflare.com/mcp

Точкой входя является наш /route/mcp.ts. ChatGPT при подключении начнёт с него, а дальше вытащит всю необходимую информацию. В README шаблона может быть указано, если нужен другой путь, если приложений несколько; но пока считаем, что корневой URL туннеля + /mcp — это то, что вам нужно.

Сохраните конфигурацию приложения. В этот момент ChatGPT делает несколько запросов к вашему приложению через туннель:

  • Читает манифест App (метаданные, инструменты и прочее).
  • Проверяет доступность MCP‑эндпоинта.
  • Получает список всех tools и ресурсов.
  • Кеширует html код всех виджетов(!)

Если всё хорошо, вы увидите своё приложение в списке Dev‑Apps. Если что‑то сломано (невалидный манифест, сервер не отвечает, туннель упал), ChatGPT покажет ошибку вроде «App unavailable» или что‑то близкое.

Важно: этот один и тот же HTTPS‑URL туннеля ChatGPT будет использовать и для вызова инструментов (MCP), и для загрузки виджета и статики. В следующем разделе разберём эти две роли по отдельности.

7. Как теперь ходят запросы: две роли вашего туннеля

Важно чётко понимать, что именно ChatGPT делает с этим URL. В архитектуре Apps SDK есть две основные точки входа: MCP‑эндпоинт и UI‑виджет.

Упрощённо цепочка выглядит так:

flowchart LR
    ChatGPT["ChatGPT (модель)"] 
    subgraph Internet
        Tunnel[HTTPS‑туннель
giftgenius-1234.trycloudflare.com] end Local["Next.js dev‑сервер httр://localhost:3000"] ChatGPT -- HTTP(S) запросы к /mcp --> Tunnel ChatGPT -- Загрузка iframe /widget --> Tunnel Tunnel --> Local

У туннеля фактически две основные роли:

  • Роль 1: MCP‑эндпоинт (инструменты). Когда модель решает вызвать инструмент (tool), она делает HTTP POST на MCP‑эндпоинт (в шаблоне это маршрут app/mcp/route.ts в Next.js) по тому же домену туннеля.
  • Роль 2: UI‑виджет и статика. Когда модель решает показать виджет, она встраивает iframe с вашим URL (обычно /widget или то, что указано в манифесте), и загрузка также идёт через туннель.

Туннель в этом смысле не «для чего‑то одного», он — единая дверь в ваш локальный App: UI, MCP, статика, всё это идёт через один и тот же публичный HTTPS‑домен.

8. Практика: проверяем цепочку «код → туннель → ChatGPT»

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

Во‑первых, запустите npm run dev и убедитесь, что http://localhost:3000 открывается в браузере.

Во‑вторых, запустите cloudflared tunnel --url http://localhost:3000 и получите публичный HTTPS‑URL. Проверьте его в другом браузере или даже на другом устройстве (например, на телефоне через мобильный интернет) — так вы точно убедитесь, что запросы идут через интернет, а не крутятся только на вашей машине.

В‑третьих, откройте ChatGPT, перейдите в Dev Mode и убедитесь, что ваше App подключено к этому URL. В Composer в ChatGPT чате выберите своё App, начните диалог и посмотрите, вставляет ли ChatGPT виджет, загружает ли он ваш UI.

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

// app/widget/page.tsx (пример)
'use client';

export default function GiftGeniusWidget() {
  return <h1>GiftGenius через туннель 🚇</h1>;
}

После сохранения файла:

  1. Дождитесь, пока Next.js перезапустит fast refresh,
  2. Зайдите в раздел ChatGPT, где вы добавляли свое приложение, и обновите (refresh) его.
  3. Откройте/обновите сессию с App в ChatGPT
  4. Наишите новый запрос к ChatGPT с просьбой отобразить ваш виджет
  5. Убедитесь, что новый текст заголовка виден уже внутри ChatGPT.

Это и есть маленький момент истины: вы только что изменили код на своей машине, и это изменение отразилось в облачном интерфейсе ChatGPT через туннель.

9. Немного про безопасность и «что именно вы выставили наружу»

Любой туннель — это не игрушка, а реальный публичный вход в вашу машину. В нашем учебном сценарии мы пробрасываем только localhost:3000, где крутится Next.js‑приложение. Это относительно безопасно, если:

  • этот порт не используется ни для чего другого;
  • у вас нет «приложения-монстра», в которое зачем‑то встроена админка базы данных, phpMyAdmin и ещё четыре демо‑сервиса.

Пара важных практических правил.

Туннель — это инструмент разработки, а не боевой продакшен. Мы сознательно используем его в Dev Mode, а не для настоящих пользователей и уж точно не для приёма денег.

Старайтесь не запускать на этом же порту (3000) никакие административные панели, базы без паролей и подобные штуки. Всё, что отвечает на этом порту, становится видимо из интернета, пока туннель жив.

Не раздавайте свой trycloudflare.com URL где попало. Да, вероятность, что кто‑то начнёт его активно сканировать, пока вы делаете учебный проект, невысока. Но привычка «ссылку на dev‑сервер кидаем куда угодно» в продакшене может аукнуться.

Позже, когда мы дойдём до тем про Vercel и production‑окружения, мы будем использовать нормальный хостинг с устойчивыми доменами и продакшен‑безопасностью, а туннель останется сугубо dev‑инструментом.

10. Типичные ошибки при работе с локальным запуском и туннелем

Итак, у нас уже есть поднятый локальный Next.js, рабочий HTTPS‑туннель и подключённый Dev Mode в ChatGPT. Напоследок — несколько типичных ошибок, которые почти у всех встречаются на первых итерациях, и как их быстро диагностировать.

Ошибка №1: попытка использовать http://localhost:3000 прямо в ChatGPT.
Иногда начинающие разработчики просто копируют этот URL в конфиг Dev Mode и удивляются, почему ChatGPT пишет, что не может достучаться до App. Напомню: localhost — это «я сам» для того, кто делает запрос. Для ChatGPT это сервера OpenAI, а не ваш ноутбук. Никаких особых логов вы при этом у себя не увидите, потому что запросы вообще не доходят до вашей машины.

Ошибка №2: запуск туннеля к несуществующему или неверному порту.
Частый сценарий: вы когда‑то давно крутили npm run dev на 3000‑м порту, сервер уже упал, но во втором терминале вы по привычке запускаете cloudflared tunnel --url http://localhost:3000. Cloudflare выдаёт вам красивый HTTPS‑домен, но при открытии — ошибка. Диагноз прост: локальный сервер не жив. Всегда сначала проверяйте http://localhost:3000 в браузере, а уже потом включайте туннель.

Ошибка №3: путаница между http:// и https:// при запуске туннеля.
Туннель сам даёт вам HTTPS снаружи, но к локальному серверу ему ходить нужно по HTTP, например http://localhost:3000. Попытка указать https://localhost:3000 часто приводит к странным ошибкам с TLS внутри или просто к недоступности. Помните правило: HTTPS — снаружи, HTTP — внутрь.

Ошибка №4: закрытый терминал с туннелем при активном тестировании в ChatGPT.
Ещё один классический случай: всё настроили, App работает в ChatGPT, потом вы случайно закрываете окно терминала с cloudflared. Спустя 10 минут возвращаетесь в ChatGPT — и видите «App unavailable». Причина проста: URL остался в настройках App, но сам туннель выключен. Запомните простое правило: пока вы тестируете App в Dev Mode, рядом всегда должен жить терминал с туннелем.

Ошибка №5: неосознанное использование нового URL после перезапуска туннеля.
В режиме quick tunnel Cloudflare при каждом запуске даёт новый *.trycloudflare.com. Если вы остановили и снова запустили cloudflared, а в ChatGPT по‑прежнему указан старый URL, ChatGPT будет честно ходить туда и получать таймауты или чужой сервис. При изменении URL туннеля всегда обновляйте его в настройках Dev Mode. Позже мы поговорим о том, как сделать стабильный dev‑домен, чтобы не бегать за URLами.

Ошибка №6: проброс лишних или опасных сервисов на тот же порт.
Иногда разработчики ради удобства запускают на 3000‑м порту не только Next.js, но и всякую «служебку»: дебаг‑панель, экспериментальный API без авторизации и так далее. Как только вы пробрасываете этот порт через туннель, все эти вещи оказываются доступны извне. Для учебного проекта, возможно, страшного не случится, но такая привычка в реальных проектах сильно повышает риск утечек и взломов. Всегда держите в голове: всё, что отвечает на порту, указанном в туннеле, смотрит в интернет.

1
Задача
ChatGPT Apps, 2 уровень, 2 лекция
Недоступна
Dev Mode URL панель (baseURL + /mcp)
Dev Mode URL панель (baseURL + /mcp)
1
Задача
ChatGPT Apps, 2 уровень, 2 лекция
Недоступна
Node-скрипт “одноразовый туннель → обнови .env.local”
Node-скрипт “одноразовый туннель → обнови .env.local”
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ