1. Навіщо взагалі думати про оточення
У типовому веброзробленні рано чи пізно зʼявляється стандартна трійка: локальна розробка, тестовий сервер і production‑оточення. У світі ChatGPT Apps усе так само, але є додаткова особливість: клієнт (ChatGPT) завжди в хмарі, навіть коли ви розробляєте «локально».
Коли все працює лише на вашому ноутбуці та ще й за випадковою адресою тунелю, виникає кілька неприємних ефектів. По‑перше, URL постійно змінюється — і ви швидко перестаєте памʼятати, до якого саме ендпойнта зараз привʼязаний Dev Mode. По‑друге, продуктивність і мережеві умови мало схожі на «бойові». По‑третє, локальне середовище часто використовує інші ключі, інші сервіси й узагалі живе ніби в паралельній реальності.
З іншого боку, жити «постійно в production» теж погана ідея. Будь‑яка правка може раптово зламати сценарії для реальних користувачів, особливо якщо у вас уже є інтеграції на кшталт Stripe, OAuth або оплати через ACP. З юридичного погляду та з погляду політик це також ризиковано: експерименти на реальних користувачах — не найкращий шлях до Store.
Тому мета цієї лекції — закріпити у вас просту, але чітку схему: є local dev, є staging, є production, а Dev Mode — це спосіб скерувати ChatGPT у потрібне оточення. А не один великий «мій ноутбук із тунелем», який інколи раптово перетворюється на production.
2. Особливість ChatGPT Apps: клієнт завжди в хмарі
У класичному SPA‑застосунку ви часто запускаєте і клієнт, і сервер локально: браузер на localhost, бекенд на 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: Оновлений чат + віджет
Тож навіть коли ви «просто тестуєте локально», ви вже працюєте з розподіленою системою: є хмарний клієнт, є мережа, є тунель і є ваш локальний сервер.
Це важливо, тому що:
- Локальне оточення — це не «усе в мене локально». Це «хмара → тунель → локальний сервер».
- Коли ви пізніше додасте 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‑ендпойнт назовні за адресою на кшталт https://abc123.ngrok.app.
Через Dev Mode у ChatGPT ви вказуєте цей публічний URL — і ChatGPT починає надсилати запити до вашого застосунку. Усе це й є оточення local dev.
Головні властивості local dev:
- Локальне середовище дає дуже швидкий цикл зворотного звʼязку. Ви змінюєте код у 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';
Тут ми:
- Уводимо типізоване перелічення оточень.
- Читаємо змінну NEXT_PUBLIC_APP_ENV (її ви пізніше задасте різними значеннями для dev/staging/prod).
- За замовчуванням вважаємо, що ми в 'local', щоб локальна розробка працювала одразу, без додаткових налаштувань.
Поки це нічого не деплоїть, але вже дає точку, від якої можна відштовхуватися: ваш код розуміє, у якому оточенні він виконується.
Далі можна, наприклад, показувати оточення прямо у віджеті, щоб не плутатися.
// app/components/EnvBadge.tsx
import { APP_ENV } from '../config/env';
export function EnvBadge() {
return <span>ENV: {APP_ENV}</span>;
}
Така маленька мітка дуже допомагає не переплутати «я зараз на staging чи в production?», особливо коли віджет зовні однаковий.
4. Staging: генеральна репетиція production‑оточення
Staging‑оточення — це «репетиція production‑оточення». Це вже не ваш ноутбук із dev‑сервером, а віддалений сервер або деплой на Vercel, куди потрапляє зібраний код.
З погляду ChatGPT staging виглядає майже як production: це зручний і стабільний HTTPS‑ендпойнт із доменом на кшталт 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 звертатиметься саме до цього ендпойнта.
До 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‑ендпойнта. Використовуй його, коли я запускаю цей застосунок». І ви можете змінювати цей URL.
Після публікації в Store у App зʼявляється офіційний production‑ендпойнт. Саме він використовуватиметься для реальних користувачів, і змінити його «просто так» уже не вийде: потрібна нова версія, ревʼю тощо.
На практиці розумна схема для вашого навчального застосунку може виглядати так:
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‑ендпойнт, де ви по черзі запускаєте локальні версії. Окремий 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 | |
|
GiftGenius Dev (Dev Mode) |
| Staging | |
|
GiftGenius Dev або GiftGenius Staging |
| Prod | |
|
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/production це інколи економить години налагодження.
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
Корисна вправа для вас одразу після лекції:
- Випишіть усі оточення, які у вас вже є: локальне з тунелем, можливо, якийсь ранній Vercel‑деплой, щось іще.
- Поруч підпишіть, які Git‑гілки туди деплояться.
- Ще поруч — які ChatGPT Apps (або конектори) куди дивляться.
- Позначте стрілочками, звідки ChatGPT ходить до кожного сервера.
Якщо ви працюєте не самі, зробіть такий файл architecture/environments.md у репозиторії. Це одразу зменшить імовірність ситуації «staging упав, але ніхто не знає, який це взагалі URL».
Щоб повʼязати це з вашим застосунком, можна в Dev Mode вже зараз завести один App GiftGenius Dev і домовитися так: за замовчуванням він дивиться на тунель локального оточення, а коли ви хочете протестувати цілий реліз — тимчасово переналаштовуєте його на staging‑URL. У наступних лекціях ви навчитеся деплоїти staging/production на Vercel і повʼязувати це зі змінними оточення.
Якщо зібрати все це в одну думку, то ставтеся до оточень і Dev Mode як до системи координат для вашого App. Локальне — для швидкої розробки, staging — для генеральної репетиції, production — для реальних користувачів, а Dev Mode — ваш перемикач між ними, а не окреме «магічне» оточення.
9. Типові помилки під час роботи з оточеннями і Dev Mode
Помилка № 1: жити тільки на localhost + тунель і вважати це production.
Такий підхід здається зручним: «навіщо мені staging і production, у мене ж тунель працює, ChatGPT підʼєднується». Але тунель має нестабільний URL, інші мережеві характеристики, і вся ця схема тримається на одному ноутбуці. Щойно вам знадобиться щось на кшталт OAuth callback, Stripe webhooks або MCP Gateway, відсутність нормального staging/production призведе до болю.
Помилка № 2: плутати Dev Mode з окремим оточенням.
Багато хто думає: «У мене є Dev Mode, отже, у мене є dev‑оточення». Насправді Dev Mode просто каже ChatGPT, куди ходити: у тунель, на staging або навіть у production. Dev Mode — це налаштування клієнта, а не сервера. Серверні оточення (local/staging/production) ви створюєте самі: деплоїте код, налаштовуєте домени й змінні оточення.
Помилка № 3: скеровувати Dev Mode на production і «трошки потестувати».
Технічно це можливо: ви можете в Dev Mode вписати production‑URL і «погратися» з App так, ніби це локальне середовище. Проблема в тому, що ви раптово починаєте тестувати на реальних користувачах, реальних даних і, можливо, реальних грошах. Будь‑яка помилка інструменту або віджета може призвести до збоїв для бойових користувачів, а ви не відразу зрозумієте, у чому саме причина. Краще тримати Dev Mode на dev/staging і використовувати Store‑App для production.
Помилка № 4: відсутність явної карти «гілка ↔ оточення ↔ URL ↔ App».
Якщо ніхто в команді не може з першого разу відповісти, яка гілка деплоїться на staging, який у нього URL і який ChatGPT App на нього дивиться, це гарантоване джерело хаосу. Починаються історії «у мене все працює, на staging — ні, а в production — ще щось третє». Проста табличка або markdown‑файл із цією картою окупається багаторазово.
Помилка № 5: недооцінювати різницю між local dev і staging.
Локально ви запускаєте dev‑сервер: у вас один набір ключів, один набір сервісів і своя мережа. На staging код уже зібраний, працює в іншому середовищі, з іншими лімітами, таймаутами й маршрутами. Якщо ви все тестуєте лише локально, а staging тримаєте «для галочки», критичні баги випливатимуть уже в production. Важливо звикнути до ланцюжка: спершу локальна розробка, потім перевірка на staging — і лише після цього реліз у production.
Помилка № 6: намагатися розвʼязувати всі проблеми через ChatGPT, ігноруючи схему оточень.
Інколи під час проблем розробники починають «питати в ChatGPT, що сталося», замість того щоб подивитися на схему: який App до якого URL привʼязаний, у якому оточенні сталося падіння, де логи. Наша сьогоднішня схема оточень — фундамент для наступної лекції, де ми системно налагоджуватимемося: дивитися логи, використовувати MCP‑інспектор і лише потім робити висновки про модель.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ