CodeGym /課程 /ChatGPT Apps /環境:local dev、staging、production + Dev Mode

環境:local dev、staging、production + Dev Mode

ChatGPT Apps
等級 7 , 課堂 0
開放

1. 為什麼需要思考環境

在一般的 Web 開發中,遲早會出現三件組合:本機開發、測試伺服器,以及 production 環境。在 ChatGPT Apps 的世界裡也一樣,但多了一個轉折:用戶端(ChatGPT)永遠在雲端,即使你在「本機」開發。

如果一切只在你的筆電上透過隨機的通道位址運作,會出現一些不愉快的情況。第一,URL 不斷變動,你也記不清 Dev Mode 目前綁到哪個 endpoint。第二,效能與網路不像真實上線環境。第三,本機環境經常使用不同的金鑰、不同的服務,等於活在平行時空。

另一方面,長期「直接在正式環境上」也不好。任何修改都可能突然影響到真實使用者的流程,特別是當你已經有 Stripe、OAuth 或 ACP 付款等整合時。從法規與政策角度也有問題:拿真實使用者當實驗對象—並不是進入 Store 的最佳做法。

因此,本講座的目標是讓你腦中形成一個簡單但嚴謹的架構:有 local dev、有 staging、有 production,還有 Dev Mode 作為把 ChatGPT 指向正確環境的方式。而不是一個「我的筆電 + 通道,偶爾突然變成正式環境」的大雜燴。

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: 對 App URL 的 HTTPS 請求
    Tunnel->>App: 代理轉發到 localhost
    App-->>Tunnel: 回應(UI/JSON)
    Tunnel-->>ChatGPT: 回應
    ChatGPT-->>User: 更新後的聊天 + 小工具

即使你「只是本機測試」,其實你已經身處分散式系統:有雲端用戶端、有網路、有通道,還有你的本機伺服器。

這一點很重要,因為:

  1. 本機環境並非全部「都在我這台」。它其實是「雲端 → 通道 → 本機伺服器」。
  2. 當你之後加入 staging 與 production,差別只在於 ChatGPT 把請求送到哪裡:通道、staging 網域,或正式網域。

3. Local dev:你現在的架構長什麼樣

我們來看看這個通用架構在你那裡現在長怎樣。
經過模組 2–6 之後,你大概會是這個樣子:

  • 由指令 npm run dev 啟動的 Next.js 開發伺服器(通常是 http://localhost:3000)。
  • 本機 MCP 伺服器(常為獨立行程,例如 http://localhost:2091)。
  • HTTPS 通道(ngrok、Cloudflare Tunnel 等),把你的 Next.js/HTTP endpoint 對外公開為像 https://abc123.ngrok.app 這樣的位址。

在 ChatGPT 的 Dev Mode 中,你把這個公開 URL 指給它,ChatGPT 便會開始呼叫你的應用。這整套就是 local dev 環境

local dev 的關鍵特性:

  • 本機環境提供非常快的回饋循環(feedback loop)。你在 VS Code 改了程式,Next.js 做 hot reload,小工具幾秒內就更新。
  • 在這裡可以任意嘗試與破壞、使用 mock 資料、測試用金鑰、各種奇怪的設定。
  • 這裡沒有真實使用者,除了你之外幾乎沒人知道這個 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 還是 prod?」的誤判,尤其當小工具在外觀上幾乎一致時。

4. Staging:正式環境的總彩排

Staging 環境就是「正式環境的彩排」。它已不是你筆電上的 dev 伺服器,而是遠端伺服器或 Vercel 部署,跑的是已編譯好的程式碼。

對 ChatGPT 而言,staging 幾乎就像 production:它是一個方便、穩定的 HTTPS endpoint,使用像 https://staging.giftgenius.app 這樣的網域,其中:

  • 程式碼已編譯完成(npm run build 成功);
  • 使用與正式環境相似的環境變數(相同名稱與格式),但搭配測試金鑰;
  • 可用的外部服務相同(Stripe sandbox、測試用 OAuth 帳號);
  • 網路拓撲與正式環境相近(例如相同的資料庫類型與區域)。

ChatGPT Apps 的脈絡下,為什麼需要 staging:

第一,staging 很適合跑 end‑to‑end 情境。例如:使用者在 ChatGPT → ChatGPT 啟動你的應用 → 小工具詢問使用者 → 呼叫 MCP tool 連到外部 API → 回傳建議 → 小工具顯示結果。這種情境在本機透過隨機通道的行為可能是一種樣子;而在 staging 環境會更接近真實:延遲、網路與資源都更貼近現實。

第二,staging 讓你測試那些在本機很難放心跑的整合,例如付款:Stripe、ACP/Instant Checkout 等。在 staging 中你設定測試金鑰、測試 webhook,完整跑一遍「大人的劇本」,但不會動到真實金流。

第三,staging 是團隊驗證的場所。若你有多位工程師、設計、QA、PM,他們需要一個共同的 URL,不依賴某台筆電是否開機、通道有沒有掛。

你可以把 staging 想成這樣:

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

    ChatGPT --> AppStaging

https://staging.giftgenius.app 這個位址背後,可能同時跑著 Next.js、MCP 伺服器、staging 資料庫等。

本講座不深入 Vercel 部署細節,這會在後續主題介紹。此刻只要把 staging 視為一個獨立環境,它在設定與 ChatGPT 的到達方式上,儘可能貼近 production。

5. Production:正式伺服器與真實使用者

Production 環境是有真實使用者 與真實金流 的地方。這裡不再是「我先在 main 快修一下看會怎樣」——任何變更都要審慎、先測試,並盡量要能回滾。

Production 網域必須穩定。它不是隨機的 ngrok URL,而是像 https://giftgenius.app 這樣的正式網域。這也是你在 App 的 Store 設定中填寫的位址:當使用者在 ChatGPT Store 發現並啟動你的應用時,ChatGPT 會呼叫的就是這個 endpoint。

對 production 環境通常有更高要求:

  • 穩定性。 低錯誤率、可預期的回應時間、在負載下也能正確運作。後續模組會談到 SLO/SLI,但直覺上就是「應用應該『幾乎一直』可用,且『幾乎總是』回應快速」。
  • 安全性。 只放必要的祕密、最低必要權限、妥善處理 PII 與金流。
  • 限制實驗。 上班時間不該再有「又重啟了 dev 伺服器」;實驗透過 feature flag、A/B 或獨立的 dev/staging 環境,而不是直接動正式伺服器。

就 ChatGPT 而言,production 已經不是 Dev Mode 的故事,而是 已發佈的 App:它透過 Store 或組織設定提供給使用者,會經過審查,且必須足夠可靠,才能通過審核。

6. Dev Mode 與正式使用 App:各自綁到什麼

最常見的誤解來了:ChatGPT 的 Dev Mode 並不是「一個獨立環境」。它更像是一個路由切換器:在你測試應用時,ChatGPT 目前看向哪個 URL。

在 Dev Mode 你可以:

  • 透過通道連到本機應用;
  • 連到 staging 環境;
  • 甚至暫時把 Dev Mode 指到 production(通常不建議這麼做)。

形式上,Dev Mode 會告訴 ChatGPT:「這是我的 App 的 manifest,這是我的 MCP/Apps SDK endpoint 的 URL。當我啟動這個應用時請用它。」而且你可以更改這個 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
https://abc123.ngrok.app] DevApp -->|staging URL| StagingEnv[Staging
https://staging.giftgenius.app] ProdApp -->|prod URL| ProdEnv[Production
https://giftgenius.app]

你把 Dev Mode 應用 GiftGenius Dev 設定為通常指向 local dev(經由通道),需要時再指向 staging。Store 應用 GiftGenius 僅綁定 production URL。

有時也會另外做一個給 QA 的 App,例如 GiftGenius Staging,只會指向 staging URL。若你有大型測試團隊很方便;在本課程中,一個 dev‑App 就足夠。

要養成這樣的思維:Dev Mode 是你與團隊的私人沙盒,可以更改 URL、調整中繼資料、重啟通道。Store 的正式 App 只看向 production,並遵守更嚴格的規則。

7. 把 Git 分支、網域與 ChatGPT App 串起來

環境不只是伺服器,還包括程式碼分支ChatGPT 中 App 的設定。你早晚會希望,光看 URL 或 App 名稱就能知道目前跑的是哪一版程式碼。

一個簡單實用的做法如下。

在開發個別功能時,使用分支 feature/*,例如 feature/new-recommendation-algo。程式碼在本機啟動並配合通道。Dev Mode ChatGPT 通常指向同一個 dev endpoint,由你們輪流啟動各自的本機版本。為每個 feature 分支都建一個獨立的 App 過猶不及。

在發佈前整合功能時,可以設一個 developstaging 分支。這個分支上的內容會自動部署到 staging 環境,例如 Vercel 預覽 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 DevGiftGenius 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,還加上 commit/branch:

// 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 設為 commit 的 SHA,小工具就會精確顯示目前運行的是哪個版本。在 staging/prod 這有時能省下數小時的除錯時間。

8. 小練習:把你的環境畫成一張圖

在深入 Vercel 與日誌之前,先「直接畫在餐巾紙上」會很有幫助。這可以是 README.md 中的 mermaid 圖、白板上的草圖,甚至筆記本中的圖片。

對我們的教學專案 GiftGenius,圖可以長這樣:

graph TD
    subgraph ChatGPT
      DevMode["Dev Mode
(你與團隊)"] Store["Store
(真實使用者)"] end subgraph Servers Local[Local dev
通道 → 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,甚至 prod。Dev Mode 是「用戶端的設定」,不是「伺服器的環境」。伺服器端的環境(local/staging/prod)要由你自己建立:部署程式碼、設定網域與環境變數。

錯誤 3:把 Dev Mode 指向 production,然後「稍微測一下」。
技術上可行:你可以在 Dev Mode 寫上 production URL,像在本機一樣玩你的 App。麻煩在於,你突然開始在真實使用者、真實資料、甚至真實金流上做測試。任何工具或小工具的錯誤,都可能讓正式使用者出問題,而你甚至一時還搞不清原因。最好讓 Dev Mode 連到 dev/staging,正式環境用 Store 的 App

錯誤 4:缺少清楚的「分支 ↔ 環境 ↔ URL ↔ App」地圖。
如果團隊中沒有任何人能立刻回答:哪些分支部署到 staging、它的 URL 是什麼、哪個 ChatGPT App 指向它,那幾乎保證會混亂。接著就會出現「在我機器上可以、在 staging 不行、在 prod 又是另一回事」的故事。一張簡單的表或 markdown 檔,能反覆為你省下時間。

錯誤 5:低估 local dev 與 staging 的差異。
在本機你啟動的是 dev 伺服器,使用一套金鑰、一組服務與一種網路;在 staging,程式碼已經編譯、在不同環境運行,有不同限制、逾時與路由。如果你只在本機測、把 staging 當裝飾,關鍵錯誤就會在 prod 才爆出來。請習慣這條鏈:先本機開發,再到 staging 驗證,最後才發佈到 production。

錯誤 6:遇到問題只想問 ChatGPT,而忽視環境架構。
有時候遇到問題,開發者會直接「問 ChatGPT 發生什麼事」,而不是先看圖:哪個 App 綁了哪個 URL、在哪個環境出錯、哪裡有日誌。我們今天建立的環境架構,就是下一講系統性除錯的基礎:看日誌、用 MCP 檢視器,最後才考慮模型本身。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION