JavaRush /Курсы /ChatGPT Apps /Окружения: local dev, staging, production + Dev Mode

Окружения: local dev, staging, production + Dev Mode

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

1. Зачем вообще думать про окружения

В обычной веб‑разработке рано или поздно появляется тройка: локальная разработка, тестовый сервер и production‑окружение. В мире ChatGPT Apps всё то же самое, но с дополнительным поворотом: клиент (ChatGPT) всегда в облаке, даже когда вы разрабатываете «на локалке».

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

С другой стороны, жить «всё время в проде» тоже плохо. Любая правка может внезапно сломать сценарии живым пользователям, особенно если у вас уже интеграции типа Stripe, OAuth или оплаты через ACP. Юридически и с точки зрения политики это тоже проблемно: эксперименты на реальных пользователях — не лучший путь в Store.

Поэтому цель этой лекции — сформировать в голове простую, но жёсткую схему: есть local dev, есть staging, есть production, и есть Dev Mode как способ направить ChatGPT в нужное окружение. А не один большой «мой ноутбук с туннелем, который иногда внезапно превращается в прод».

2. Особенность ChatGPT Apps: клиент всегда в облаке

В классическом SPA‑приложении вы часто запускаете и клиент, и сервер у себя локально: браузер на localhost, backend на localhost, и всё счастливо общается внутри одной машины.

В ChatGPT Apps этого не происходит. Клиент (ChatGPT + ваш виджет) всегда живёт в инфраструктуре OpenAI. Даже если код вашего приложения крутится на вашем ноутбуке, запрос идёт так:

sequenceDiagram
    participant User as Пользователь
    participant ChatGPT as ChatGPT (облако)
    participant Tunnel as HTTPS-туннель
    participant App as Ваш Next.js + MCP

    User->>ChatGPT: Сообщение / клик по виджету
    ChatGPT->>Tunnel: HTTPS-запрос к URL App
    Tunnel->>App: Проксирование на localhost
    App-->>Tunnel: Ответ (UI/JSON)
    Tunnel-->>ChatGPT: Ответ
    ChatGPT-->>User: Обновлённый чат + виджет

Даже когда вы «просто тестируете локально», вы уже живёте в распределённой системе: есть облачный клиент, есть сеть, есть туннель, есть ваш локальный сервер.

Это важно, потому что:

  1. Локальное окружение — это не «всё у меня локально». Это «облако → туннель → локальный сервер».
  2. Когда вы позже добавите staging и production, схема будет отличаться только тем, куда именно ChatGPT шлёт запросы: в туннель, на staging‑домен или на боевой домен.

3. Local dev: как выглядит ваша текущая схема

Давайте посмотрим, как эта общая схема выглядит у вас сейчас.
После модулей 2–6 у вас, скорее всего, такая картинка:

  • Next.js dev‑сервер, запущенный командой npm run dev (обычно http://localhost:3000).
  • Локальный MCP‑сервер (часто это отдельный процесс, например http://localhost:2091).
  • HTTPS‑туннель (ngrok, Cloudflare Tunnel и т.п.), который публикует ваш Next.js/HTTP endpoint наружу по адресу вроде https://abc123.ngrok.app.

Через Dev Mode в ChatGPT вы указываете этот публичный URL, и ChatGPT начинает ходить к вашему приложению. Всё это — local dev окружение.

Главные свойства local dev:

  • Локальная среда даёт очень быстрый feedback‑loop. Вы меняете код в VS Code, Next.js делает hot reload, виджет обновляется через пару секунд.
  • Здесь можно ломать всё что угодно, использовать мок‑данные, тестовые ключи, странные конфиги.
  • Здесь нет реальных пользователей, мало кто, кроме вас, вообще знает об этом URL.

Обычно это выглядит так:

graph LR
    subgraph Dev Laptop
      Next[Next.js dev server]
      MCP[MCP server]
    end

    ChatGPT((ChatGPT Cloud))
    Tunnel[[HTTPS туннель]]

    ChatGPT --> Tunnel --> Next
    Next --> MCP

Чтобы дальше не путаться между local/staging/production, полезно, чтобы само приложение «знало», где оно сейчас работает. С точки зрения кода в вашем приложении полезно явно зафиксировать, что вы сейчас в dev‑окружении. Самый простой шаг — ввести маленький модуль конфигурации среды.

Например, создадим файл app/config/env.ts:

// app/config/env.ts
export type AppEnv = 'local' | 'staging' | 'production';

export const APP_ENV: AppEnv =
  (process.env.NEXT_PUBLIC_APP_ENV as AppEnv) ?? 'local';

export const isProd = APP_ENV === 'production';

Здесь мы:

  1. Вводим типизированное перечисление окружений.
  2. Читаем переменную NEXT_PUBLIC_APP_ENV (её вы позже зададите разными значениями на dev/staging/prod).
  3. По умолчанию считаем, что мы в 'local', чтобы локальная разработка работала «из коробки».

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

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

// app/components/EnvBadge.tsx
import { APP_ENV } from '../config/env';

export function EnvBadge() {
  return <span>ENV: {APP_ENV}</span>;
}

Такой маленький бейдж серьёзно помогает не перепутать «я сейчас на staging или на проде?», особенно когда виджет внешне одинаковый.

4. Staging: генеральная репетиция production‑окружения

Staging‑окружение — это «репетиция production‑окружения». Это уже не ваш ноутбук с dev‑сервером, а удалённый сервер или Vercel‑деплой, на который заливается собранный код.

С точки зрения ChatGPT staging выглядит почти как production: это удобный, стабильный HTTPS‑endpoint с доменом вроде https://staging.giftgenius.app, где:

  • код уже собран (npm run build прошёл успешно);
  • используются переменные окружения, похожие на боевые (те же имена, тот же формат), но с тестовыми ключами;
  • доступны те же внешние сервисы (Stripe sandbox, тестовые OAuth‑аккаунты);
  • топология сети похожа на боевую (например, тот же тип базы и тот же регион).

Зачем нужен staging в контексте ChatGPT Apps:

Во‑первых, именно на staging удобно гонять end‑to‑end сценарии. Например: пользователь в ChatGPT → ChatGPT запускает ваше приложение → виджет спрашивает пользователя → вызывается MCP‑tool, который лезет в внешнее API → возвращает рекомендации → виджет показывает результат. Такой сценарий на локалке через случайный туннель может вести себя одним образом. А в staging‑окружении — уже по‑другому: там латентность, сеть и ресурсы ближе к реальности.

Во‑вторых, staging позволяет тестировать интеграции, которые просто страшно крутить на локалке. Например, платежи: Stripe, ACP/Instant Checkout и т.п. В staging вы конфигурируете тестовые ключи, тестовые вебхуки и прогоняете сценарии «по‑взрослому», но без реальных денег.

В‑третьих, staging — это место командной проверки. Если у вас несколько разработчиков, дизайнер, QA, продакт — им нужен общий URL, который не зависит от того, чей ноутбук сейчас включен и у кого упал туннель.

Удобно представлять staging так:

graph LR
    ChatGPT((ChatGPT Cloud))
    AppStaging["GiftGenius Staging  httрs://staging.giftgenius.app"]

    ChatGPT --> AppStaging

А уже внутри https://staging.giftgenius.app у вас может крутиться Next.js, MCP‑сервер, staging‑БД и всё остальное.

В этой лекции мы не уходим в детали деплоя на Vercel, это задача следующих тем. Сейчас важно просто принять как данность: staging — это отдельное окружение, максимально похожее на production по конфигурации и тому, как ChatGPT до него добирается.

5. Production: боевой сервер и реальные пользователи

Production‑окружение — это то место, куда приходят реальные пользователи и реальные деньги. Здесь уже нет «я сейчас быстро поправлю в main, посмотрю, что будет» — любые изменения должны быть осознанными, протестированными и, по возможности, с возможностью отката.

Production‑домен должен быть стабильным. Это не рандомный ngrok‑URL, а нормальное имя вида https://giftgenius.app или что‑то подобное. Именно этот адрес вы указываете в настройках App для Store: когда пользователь находит ваше приложение в ChatGPT Store и запускает его, ChatGPT будет звать именно этот endpoint.

К production‑окружению обычно предъявляются повышенные требования:

  • Стабильность. Низкий процент ошибок, предсказуемое время ответа, корректная работа под нагрузкой. В более поздних модулях мы будем говорить про SLO/SLI, но интуитивно это «приложение должно “почти всегда” работать и “почти всегда” отвечать быстро».
  • Безопасность. Только нужные секреты, минимально необходимые пермишены, аккуратная работа с PII и деньгами.
  • Ограничение экспериментов. Никакого «опять перезапустил dev‑сервер» в середине рабочего дня; эксперименты через фичефлаги, A/B или отдельное dev/staging‑окружение, а не через прямое ковыряние боевого сервера.

В терминах ChatGPT production — это история уже не про Dev Mode, а про опубликованный App: он доступен пользователям через Store или настройки организации, проходит ревью и должен быть достаточно надёжным, чтобы не позориться перед модерацией.

6. Dev Mode vs прод‑использование App: что к чему привязано

Теперь самая частая путаница: Dev Mode ChatGPT не является «отдельным окружением». Это скорее переключатель маршрута: на какой URL ChatGPT сейчас смотрит, когда вы тестируете приложение.

В Dev Mode вы можете:

  • подключить локальное приложение через туннель;
  • подключить staging‑окружение;
  • даже временно направить Dev Mode на production (что обычно делать не стоит).

Формально Dev Mode говорит ChatGPT: «Вот манифест моего App, вот URL моего MCP/Apps SDK‑endpoint. Используй его, когда я запускаю это приложение». И вы можете этот URL менять.

После публикации в Store у App появляется официальный production‑endpoint. Именно он будет использоваться для реальных пользователей, и менять его просто так уже нельзя: нужна новая версия, ревью и т.д.

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

graph TD
    subgraph Dev Mode
      DevApp["GiftGenius Dev App
(Dev Mode)"] end subgraph Store ProdApp["GiftGenius
(Store App)"] end UserDev[Вы / команда] --> DevApp UserProd[Реальные пользователи] --> ProdApp DevApp -->|URL туннеля| LocalEnv[Local dev
httрs://abc123.ngrok.app] DevApp -->|staging URL| StagingEnv[Staging
httрs://staging.giftgenius.app] ProdApp -->|prod URL| ProdEnv[Production
httрs://giftgenius.app]

Dev Mode‑приложение GiftGenius Dev вы настраиваете так, чтобы оно обычно смотрело на local dev (через туннель), а когда нужно — на staging. Store‑приложение GiftGenius привязано строго к production‑URL.

Иногда делают ещё и отдельный App для QA, вроде GiftGenius Staging, который смотрит только на staging‑URL. Это удобно, если у вас есть большая команда тестировщиков; в рамках курса достаточно одного dev‑App’а.

Важно привыкнуть мыслить так: Dev Mode — это личная песочница для вас и команды, где можно менять URL, править метаданные, перезапускать туннель. Production‑App в Store смотрит только на production и живёт по более строгим правилам.

7. Связка Git‑веток, доменов и ChatGPT App

Окружения — это не только сервера. Это ещё и ветки кода и конфигурации App в ChatGPT. Рано или поздно вы захотите, чтобы по одному взгляду на URL или название App можно было понять, какая именно версия кода там крутится.

Простой минимальный подход такой.

Для разработки отдельных фич вы используете ветки feature/*, например feature/new-recommendation-algo. Код запускаете локально + туннель. Dev Mode ChatGPT обычно смотрит на один и тот же dev‑endpoint, где вы по очереди запускаете локальные версии. Отдельный App под каждую feature‑ветку — перебор.

Для интеграции фич перед релизом можно завести ветку develop или staging. Всё, что в этой ветке, автоматически деплоится на staging‑окружение, например на Vercel preview URL вида https://giftgenius-staging.vercel.app. Для него можно завести отдельный Dev Mode‑App или периодически перенастраивать общий Dev‑App на этот URL.

Ветка main (или master) — это только протестированный код. Именно она деплоится на production‑URL и привязана к Store‑приложению GiftGenius.

Выглядеть это может примерно так:

Окружение Git‑ветка URL ChatGPT App
Local dev
feature/*
https://abc123.ngrok.app
GiftGenius Dev (Dev Mode)
Staging
develop / staging
https://staging.gift...
GiftGenius Dev или GiftGenius Staging
Prod
main
https://giftgenius.app
GiftGenius (Store)

Помните APP_ENV из app/config/env.ts? Значения 'local'/'staging'/'production' здесь прямо соответствуют столбцу «Окружение»: в local dev вы запускаете приложение с APP_ENV=local, staging‑деплой — с APP_ENV=staging, а production — с APP_ENV=production.

Такая табличка — не бюрократия, а способ не отлаживаться по схеме «а что сейчас вообще за версия крутится на этом домене?».

В самом коде можно немного усилить эту связку. Например, отображать не только ENV, но и коммит/ветку в debug‑режиме виджета:

// app/config/buildInfo.ts
export const BUILD_COMMIT = process.env.NEXT_PUBLIC_BUILD_COMMIT ?? 'dev';
export const BUILD_ENV = process.env.NEXT_PUBLIC_APP_ENV ?? 'local';
// app/components/BuildInfo.tsx
import { BUILD_COMMIT, BUILD_ENV } from '../config/buildInfo';

export function BuildInfo() {
  return <small>Build: {BUILD_ENV}@{BUILD_COMMIT}</small>;
}

Если вы при деплое подставляете в NEXT_PUBLIC_BUILD_COMMIT SHA коммита, в виджете будет честно написано, какой именно код сейчас работает. В staging/prod это иногда спасает часы отладки.

8. Мини‑практика: рисуем схему своих окружений

Прежде чем уходить в Vercel и логи, полезно буквально «нарисовать на салфетке» схему своих окружений. Это может быть mermaid‑диаграмма в README.md, набросок на доске или даже картинка в блокноте.

Для нашего учебного GiftGenius схема может выглядеть так:

graph TD
    subgraph ChatGPT
      DevMode["Dev Mode
(вы и команда)"] Store["Store
(реальные пользователи)"] end subgraph Servers Local[Local dev
Tunnel → localhost] Staging[Staging
staging.giftgenius.app] Prod[Production
giftgenius.app] end DevMode --> Local DevMode --> Staging Store --> Prod

Полезное упражнение для вас прямо после лекции:

  1. Выпишите все окружения, которые у вас уже есть: локалка с туннелем, возможно, какой‑то ранний Vercel‑деплой, что‑то ещё.
  2. Рядом подпишите, какие Git‑ветки туда деплоятся.
  3. Ещё рядом — какие ChatGPT Apps (или коннекторы) куда смотрят.
  4. Отметьте стрелочками, откуда ChatGPT ходит в каждый сервер.

Если вы работаете не в одиночку, сделайте такой файл architecture/environments.md в репозитории. Это сразу уменьшит вероятность «у нас staging упал, но никто не знает, какой это вообще URL».

Чтобы связать это с вашим приложением, можно в Dev Mode сейчас же завести один App GiftGenius Dev и решить: по умолчанию он смотрит на туннель локального окружения, а когда вы хотите протестировать целый релиз, временно перенастраиваете его на staging‑URL. В следующих лекциях вы уже научитесь деплоить staging/prod на Vercel и связывать это с переменными окружения.

Если всё это собрать в одну мысль: относитесь к окружениям и Dev Mode как к системе координат для вашего App. Локалка — для быстрой разработки, staging — для генеральной репетиции, production — для реальных пользователей, а Dev Mode — ваш переключатель между ними, а не отдельное магическое окружение.

9. Типичные ошибки при работе с окружениями и Dev Mode

Ошибка №1: жить только на localhost + туннель и считать это продом.
Такой подход кажется удобным: «зачем мне staging и prod, у меня же туннель работает, ChatGPT подключается». Но у туннеля нестабильный URL, другие характеристики сети, и вся эта схема держится на одном ноутбуке. Как только вам понадобится что‑то вроде OAuth callback, Stripe webhooks или MCP Gateway, отсутствие нормального staging/prod приведёт к боли.

Ошибка №2: путать Dev Mode с отдельным окружением.
Многие думают: «У меня есть Dev Mode, значит, у меня есть dev‑окружение». На самом деле Dev Mode просто говорит ChatGPT, куда ходить: в туннель, на staging или даже в прод. Dev Mode — это настройка клиента, а не сервера. Серверные окружения (local/staging/prod) вы создаёте сами: деплоите код, настраиваете домены, переменные окружения.

Ошибка №3: направлять Dev Mode на production и «немножко потестировать».
Технически это возможно: вы можете в Dev Mode вписать production‑URL и поиграться с App так, будто это локалка. Проблема в том, что вы внезапно начинаете тестировать на реальных пользователях, реальных данных и, возможно, реальных деньгах. Любая ошибка инструмента или виджета может привести к сбоям для боевых пользователей, а вы даже не сразу поймёте, откуда ноги растут. Лучше держать Dev Mode на dev/staging и использовать Store‑App для production.

Ошибка №4: отсутствие явной карты «ветка ↔ окружение ↔ URL ↔ App».
Если никто в команде не может с первого раза ответить, какая ветка деплоится на staging, какой у него URL и какой ChatGPT App на него смотрит, это гарантированный источник хаоса. Начинаются истории «у меня всё работает, на staging нет, на проде ещё что‑то третье». Простая табличка или markdown‑файл с этой картой окупается многократно.

Ошибка №5: недооценивать разницу между local dev и staging.
На локалке вы запускаете dev‑сервер, у вас один набор ключей, один набор сервисов и одна сеть. На staging код уже собран, запускается в другом окружении, с другими лимитами, таймаутами и маршрутами. Если вы всё тестируете только на локалке, а staging держите «для галочки», критические баги будут вылезать уже в проде. Важно привыкнуть к цепочке: сначала локальная разработка, затем проверка на staging, и только потом релиз в production.

Ошибка №6: пытаться решать все проблемы через ChatGPT, игнорируя схему окружений.
Иногда при проблемах разработчики начинают «спрашивать ChatGPT, что случилось», вместо того чтобы посмотреть на картинку: какой App к какому URL привязан, в каком окружении упало, где логи. Наша сегодняшняя схема окружений — фундамент для следующей лекции, где мы будем системно отлаживаться: смотреть логи, использовать MCP‑инспектор и только потом винить модель.

1
Задача
ChatGPT Apps, 7 уровень, 0 лекция
Недоступна
ENV-бейдж для виджета (local / staging / production)
ENV-бейдж для виджета (local / staging / production)
1
Задача
ChatGPT Apps, 7 уровень, 0 лекция
Недоступна
Единый baseURL для окружений + удобный MCP URL для Dev Mode
Единый baseURL для окружений + удобный MCP URL для Dev Mode
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ