CodeGym /Corsi /ChatGPT Apps /Ambienti: local dev, staging, production + Dev Mode

Ambienti: local dev, staging, production + Dev Mode

ChatGPT Apps
Livello 7 , Lezione 0
Disponibile

1. Perché ha senso pensare agli ambienti

Nel normale sviluppo web, prima o poi compaiono tre ambienti: sviluppo locale, server di test e ambiente di produzione. Nel mondo delle ChatGPT Apps è lo stesso, ma con una particolarità: il client (ChatGPT) è sempre nel cloud, anche quando sviluppi «in locale».

Se tutto gira solo sul tuo laptop dietro un indirizzo casuale di un tunnel, sorgono diversi effetti spiacevoli. Primo, l’URL cambia continuamente e non ricordi a quale endpoint sia collegato ora il Dev Mode. Secondo, prestazioni e rete non assomigliano alle condizioni di produzione. Terzo, l’ambiente locale spesso usa chiavi diverse, servizi diversi e in generale vive in una realtà parallela.

D’altro canto, vivere «sempre in produzione» è altrettanto negativo. Qualsiasi modifica può improvvisamente rompere scenari per utenti reali, specialmente se hai già integrazioni come Stripe, OAuth o pagamenti tramite ACP. Anche dal punto di vista legale e delle policy è problematico: fare esperimenti su utenti reali non è la via migliore per lo Store.

Perciò l’obiettivo di questa lezione è fissare in mente uno schema semplice ma rigoroso: esistono local dev, staging, production e il Dev Mode come modo per indirizzare ChatGPT verso l’ambiente giusto. Non un grande «mio laptop con tunnel, che a volte si trasforma all’improvviso in produzione».

2. Particolarità delle ChatGPT Apps: il client è sempre nel cloud

In un’applicazione SPA classica spesso avvii sia il client sia il server in locale: browser su localhost, backend su localhost, e tutto comunica felicemente all’interno della stessa macchina.

Nelle ChatGPT Apps questo non accade. Il client (ChatGPT + il tuo widget) vive sempre nell’infrastruttura OpenAI. Anche se il codice della tua applicazione gira sul tuo laptop, la richiesta segue questo percorso:

sequenceDiagram
    participant User as Utente
    participant ChatGPT as ChatGPT (cloud)
    participant Tunnel as Tunnel HTTPS
    participant App as Il tuo Next.js + MCP

    User->>ChatGPT: Messaggio / clic sul widget
    ChatGPT->>Tunnel: Richiesta HTTPS verso l'URL dell'App
    Tunnel->>App: Proxy verso localhost
    App-->>Tunnel: Risposta (UI/JSON)
    Tunnel-->>ChatGPT: Risposta
    ChatGPT-->>User: Chat aggiornata + widget

Anche quando «stai solo testando in locale», sei già in un sistema distribuito: c’è un client nel cloud, la rete, un tunnel e il tuo server locale.

Questo è importante perché:

  1. L’ambiente locale non è «tutto in locale». È «cloud → tunnel → server locale».
  2. Quando aggiungerai staging e production, lo schema differirà solo per la destinazione delle richieste di ChatGPT: il tunnel, il dominio di staging o il dominio di produzione.

3. Local dev: com’è il tuo schema attuale

Vediamo come appare questo schema generale nel tuo caso.
Dopo i moduli 2–6, con ogni probabilità hai questa situazione:

  • Dev server di Next.js avviato con il comando npm run dev (di solito http://localhost:3000).
  • Server MCP locale (spesso un processo separato, ad esempio http://localhost:2091).
  • Tunnel HTTPS (ngrok, Cloudflare Tunnel, ecc.) che espone il tuo endpoint Next.js/HTTP all’esterno a un indirizzo tipo https://abc123.ngrok.app.

Attraverso il Dev Mode in ChatGPT indichi questo URL pubblico e ChatGPT inizia a chiamare la tua applicazione. Tutto questo è l’ambiente local dev.

Caratteristiche principali del local dev:

  • L’ambiente locale offre un feedback loop molto rapido. Modifichi il codice in VS Code, Next.js fa hot reload, il widget si aggiorna in pochi secondi.
  • Qui puoi rompere qualsiasi cosa, usare dati fittizi (mock), chiavi di test, configurazioni insolite.
  • Non ci sono utenti reali; pochi, oltre a te, conoscono questo URL.

Di solito appare così:

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

    ChatGPT((ChatGPT Cloud))
    Tunnel[[Tunnel HTTPS]]

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

Per non confonderti tra local/staging/production, è utile che l’applicazione «sappia» dove sta girando. Dal punto di vista del codice, è utile fissare esplicitamente che sei in un ambiente di dev. Il passo più semplice è introdurre un piccolo modulo di configurazione dell’ambiente.

Per esempio, creiamo il file 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';

Qui:

  1. Introduciamo un elenco tipizzato degli ambienti.
  2. Leggiamo la variabile NEXT_PUBLIC_APP_ENV (che imposterai poi con valori diversi su dev/staging/prod).
  3. Per impostazione predefinita assumiamo 'local', in modo che lo sviluppo locale funzioni «out of the box».

Per ora non fa alcun deploy, ma fornisce già un punto di partenza: il tuo codice capisce in quale ambiente sta girando.

Poi puoi, per esempio, mostrare l’ambiente direttamente nel widget, per evitare confusione.

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

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

Un piccolo badge del genere aiuta molto a non confondere «sono su staging o su produzione?», soprattutto quando il widget è identico nell’aspetto.

4. Staging: la prova generale dell’ambiente di produzione

L’ambiente di staging è la «prova generale della produzione». Non è più il tuo laptop con il dev server, ma un server remoto o un deploy su Vercel su cui viene caricato il codice buildato.

Dal punto di vista di ChatGPT lo staging sembra quasi la produzione: è un endpoint HTTPS comodo e stabile, con un dominio tipo https://staging.giftgenius.app, dove:

  • il codice è già buildato (npm run build eseguito con successo);
  • si usano variabili d’ambiente simili a quelle di produzione (stessi nomi, stesso formato), ma con chiavi di test;
  • sono disponibili gli stessi servizi esterni (Stripe sandbox, account OAuth di test);
  • la topologia di rete è simile a quella di produzione (ad esempio stesso tipo di database e stessa regione).

Perché serve lo staging nel contesto delle ChatGPT Apps:

Primo, è proprio su staging che conviene eseguire scenari end‑to‑end. Per esempio: utente in ChatGPT → ChatGPT avvia la tua applicazione → il widget fa domande all’utente → si invoca un MCP tool che chiama un’API esterna → restituisce raccomandazioni → il widget mostra il risultato. Uno scenario del genere in locale attraverso un tunnel casuale può comportarsi in un modo; in staging può comportarsi diversamente: latenza, rete e risorse sono più vicine alla realtà.

Secondo, lo staging consente di testare integrazioni che fanno paura da far girare in locale. Per esempio i pagamenti: Stripe, ACP/Instant Checkout, ecc. In staging configuri chiavi di test, webhook di test ed esegui gli scenari «seri» ma senza denaro reale.

Terzo, lo staging è il luogo della verifica di squadra. Se avete più sviluppatori, designer, QA, product — serve un URL comune che non dipende da quale laptop sia acceso o da chi abbia il tunnel caduto.

È comodo immaginare lo staging così:

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

    ChatGPT --> AppStaging

E all’interno di https://staging.giftgenius.app possono girare Next.js, il server MCP, il database di staging e tutto il resto.

In questa lezione non entriamo nei dettagli del deploy su Vercel: è materia delle prossime unità. Per ora è importante accettare come dato di fatto che lo staging è un ambiente separato, il più possibile simile alla produzione per configurazione e per il modo in cui ChatGPT lo raggiunge.

5. Production: server in esercizio e utenti reali

L’ambiente di produzione è il luogo in cui arrivano utenti reali e denaro reale. Qui non esiste «faccio in fretta una modifica su main e vedo cosa succede»: ogni cambiamento deve essere consapevole, testato e, se possibile, reversibile.

Il dominio di produzione deve essere stabile. Non un URL casuale di ngrok, ma un nome normale come https://giftgenius.app o simili. È proprio questo indirizzo che indichi nelle impostazioni dell’App per lo Store: quando l’utente trova la tua app nel ChatGPT Store e la avvia, ChatGPT userà proprio questo endpoint.

Per l’ambiente di produzione si richiedono di solito requisiti più severi:

  • Stabilità. Bassa percentuale di errori, tempi di risposta prevedibili, funzionamento corretto sotto carico. In moduli successivi parleremo di SLO/SLI, ma intuitivamente significa «l’applicazione deve funzionare “quasi sempre” e rispondere “quasi sempre” rapidamente».
  • Sicurezza. Solo i segreti necessari, permessi minimi indispensabili, gestione accorta di PII e denaro.
  • Limitazione degli esperimenti. Niente «ho riavviato di nuovo il dev server» in pieno giorno lavorativo; gli esperimenti passano tramite feature flag, A/B test o ambienti separati di dev/staging, non toccando direttamente il server di produzione.

In termini di ChatGPT, la produzione non riguarda più il Dev Mode, ma l’App pubblicata: è accessibile agli utenti tramite Store o impostazioni dell’organizzazione, passa una revisione e dev’essere abbastanza affidabile da non fare brutta figura davanti alla moderazione.

6. Dev Mode vs uso in produzione dell’App: cosa è collegato a cosa

Ecco l’equivoco più frequente: il Dev Mode di ChatGPT non è un «ambiente separato». È piuttosto un commutatore di routing: a quale URL ChatGPT guarda quando testi l’applicazione.

Nel Dev Mode puoi:

  • collegare un’app locale tramite tunnel;
  • collegare l’ambiente di staging;
  • addirittura puntare temporaneamente il Dev Mode verso la produzione (di solito non consigliato).

Formalmente il Dev Mode dice a ChatGPT: «Ecco il manifest della mia App, ecco l’URL del mio endpoint MCP/Apps SDK. Usalo quando avvio questa app». E puoi cambiare questo URL.

Dopo la pubblicazione nello Store, la tua App ottiene un endpoint di produzione ufficiale. Sarà quello usato dagli utenti reali e non lo si può modificare così facilmente: serve una nuova versione, una revisione, ecc.

In pratica, uno schema ragionevole per la tua app didattica può essere questo:

graph TD
    subgraph Dev Mode
      DevApp["GiftGenius Dev App
(Dev Mode)"] end subgraph Store ProdApp["GiftGenius
(Store App)"] end UserDev[Tu / il team] --> DevApp UserProd[Utenti reali] --> ProdApp DevApp -->|URL del tunnel| LocalEnv[Dev locale
https://abc123.ngrok.app] DevApp -->|URL di staging| StagingEnv[Staging
https://staging.giftgenius.app] ProdApp -->|URL di produzione| ProdEnv[Produzione
https://giftgenius.app]

Configuri l’app in Dev Mode GiftGenius Dev in modo che di solito punti al local dev (tramite tunnel) e, quando necessario, allo staging. L’app nello Store GiftGenius è legata rigidamente all’URL di produzione.

A volte si crea anche un’App separata per il QA, tipo GiftGenius Staging, che punta solo all’URL di staging. È comodo se hai un grande team di tester; nel corso è sufficiente una sola App di dev.

È importante abituarsi a pensare così: il Dev Mode è una sandbox personale per te e il tuo team, dove puoi cambiare l’URL, modificare i metadati, riavviare il tunnel. L’App di produzione nello Store guarda solo alla produzione e vive con regole più rigide.

7. Collegare branch Git, domini e la App di ChatGPT

Gli ambienti non sono solo server. Sono anche branch del codice e configurazioni dell’App in ChatGPT. Prima o poi vorrai che da uno sguardo all’URL o al nome dell’App si capisca quale versione del codice ci sta girando.

Un approccio minimo e semplice è questo.

Per lo sviluppo di singole feature usi branch feature/*, per esempio feature/new-recommendation-algo. Esegui il codice in locale + tunnel. Il Dev Mode di ChatGPT di solito guarda allo stesso endpoint di dev, dove avvii a turno le versioni locali. Un’App separata per ogni branch feature è eccessivo.

Per integrare le feature prima del rilascio puoi creare un branch develop o staging. Tutto ciò che finisce in questo branch viene automaticamente deployato sull’ambiente di staging, per esempio su un URL di anteprima Vercel del tipo https://giftgenius-staging.vercel.app. Per questo puoi creare una App separata in Dev Mode oppure riconfigurare periodicamente la App di Dev comune su questo URL.

Il branch main (o master) contiene solo codice testato. È quello che viene deployato sull’URL di produzione ed è collegato all’app nello Store GiftGenius.

Può apparire più o meno così:

Ambiente Branch Git URL ChatGPT App
Local dev
feature/*
https://abc123.ngrok.app
GiftGenius Dev (Dev Mode)
Staging
develop / staging
https://staging.gift...
GiftGenius Dev oppure GiftGenius Staging
Prod
main
https://giftgenius.app
GiftGenius (Store)

Ti ricordi APP_ENV in app/config/env.ts? I valori 'local'/'staging'/'production' qui corrispondono direttamente alla colonna «Ambiente»: in local dev avvii l’app con APP_ENV=local, il deploy di staging con APP_ENV=staging, e la produzione con APP_ENV=production.

Questa tabella non è burocrazia, ma un modo per evitare il debug alla «ma quale versione sta girando su questo dominio?».

Nel codice puoi rafforzare un po’ questo collegamento. Ad esempio, mostrare non solo l’ENV, ma anche il commit/branch nella modalità debug del widget:

// 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>;
}

Se in fase di deploy inserisci in NEXT_PUBLIC_BUILD_COMMIT lo SHA del commit, nel widget comparirà quale codice sta effettivamente girando in quel momento. In staging/prod questo a volte salva ore di debug.

8. Mini‑pratica: disegna lo schema dei tuoi ambienti

Prima di passare a Vercel e ai log, è utile letteralmente «disegnare su un tovagliolo» lo schema dei tuoi ambienti. Può essere un diagramma mermaid in README.md, uno schizzo alla lavagna o anche un’immagine in un quaderno.

Per il nostro GiftGenius didattico, lo schema può essere così:

graph TD
    subgraph ChatGPT
      DevMode["Dev Mode
(tu e il team)"] Store["Store
(utenti reali)"] end subgraph Servers Local[Dev locale
Tunnel → localhost] Staging[Staging
staging.giftgenius.app] Prod[Produzione
giftgenius.app] end DevMode --> Local DevMode --> Staging Store --> Prod

Esercizio utile da fare subito dopo la lezione:

  1. Elenca tutti gli ambienti che hai già: locale con tunnel, forse un primo deploy su Vercel, altro.
  2. Accanto, annota quali branch Git vengono deployati lì.
  3. Ancora accanto, quali ChatGPT Apps (o connettori) guardano a dove.
  4. Segna con frecce da dove ChatGPT raggiunge ciascun server.

Se non lavori da solo, crea un file architecture/environments.md nel repository. Ridurrà subito la probabilità di «è caduto lo staging e nessuno sa nemmeno quale URL sia».

Per collegarlo alla tua app, nel Dev Mode puoi creare subito un’App GiftGenius Dev e decidere: per impostazione predefinita guarda al tunnel dell’ambiente locale, e quando vuoi testare un intero rilascio la riconfiguri temporaneamente sull’URL di staging. Nelle prossime lezioni imparerai a fare il deploy di staging/prod su Vercel e a collegarlo alle variabili d’ambiente.

Se mettiamo tutto in un unico pensiero: considera ambienti e Dev Mode come il sistema di coordinate della tua App. Locale — per lo sviluppo rapido, staging — per la prova generale, produzione — per gli utenti reali, e Dev Mode — il tuo selettore tra questi, non un ambiente magico a sé.

9. Errori tipici nel lavoro con ambienti e Dev Mode

Errore n. 1: vivere solo su localhost + tunnel e scambiarlo per la produzione.
Sembra comodo: «a cosa mi serve staging e prod, tanto il tunnel funziona e ChatGPT si collega». Ma il tunnel ha un URL instabile, caratteristiche di rete diverse, e tutto dipende da un singolo laptop. Appena ti servirà qualcosa come un OAuth callback, webhook Stripe o MCP Gateway, l’assenza di veri ambienti di staging/prod porterà dolore.

Errore n. 2: confondere il Dev Mode con un ambiente separato.
Molti pensano: «Ho il Dev Mode, quindi ho l’ambiente di dev». In realtà il Dev Mode dice solo a ChatGPT dove andare: tunnel, staging o persino produzione. Il Dev Mode è una configurazione del client, non del server. Gli ambienti lato server (local/staging/prod) li crei tu: deploy del codice, domini, variabili d’ambiente.

Errore n. 3: puntare il Dev Mode alla produzione per “fare un po’ di test”.
Tecnicamente è possibile: puoi inserire l’URL di produzione nel Dev Mode e giocare con l’App come fosse locale. Il problema è che inizi a testare su utenti reali, dati reali e, forse, denaro reale. Qualsiasi errore dello strumento o del widget può causare disservizi agli utenti di produzione, e potresti non capire subito da dove derivino. Meglio tenere il Dev Mode su dev/staging e usare l’App dello Store per la produzione.

Errore n. 4: assenza di una mappa esplicita «branch ↔ ambiente ↔ URL ↔ App».
Se nessuno nel team sa rispondere al volo a quale branch venga deployato lo staging, quale sia il suo URL e quale App di ChatGPT lo punti, è una fonte sicura di caos. Iniziano le storie «da me funziona, su staging no, in produzione è ancora diverso». Una semplice tabella o un file markdown con questa mappa ripaga ampiamente.

Errore n. 5: sottovalutare la differenza tra local dev e staging.
In locale avvii un dev server, hai un set di chiavi, un set di servizi e una rete. In staging il codice è già buildato, gira in un altro ambiente, con limiti, timeout e percorsi diversi. Se testi tutto solo in locale e lo staging lo tieni «per forma», i bug critici emergeranno già in produzione. È importante abituarsi alla catena: prima sviluppo locale, poi verifica su staging e solo dopo rilascio in produzione.

Errore n. 6: provare a risolvere tutti i problemi con ChatGPT ignorando lo schema degli ambienti.
A volte, di fronte ai problemi, gli sviluppatori iniziano a «chiedere a ChatGPT cosa sia successo» invece di guardare allo schema: quale App è collegata a quale URL, in quale ambiente è caduto, dove sono i log. Il nostro schema degli ambienti di oggi è il fondamento per la prossima lezione, in cui effettueremo un debug sistematico: guardare i log, usare l’MCP inspector e solo dopo “incolpare” il modello.

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