CodeGym /Cursos /ChatGPT Apps /Deploy na Vercel: repositório, variáveis de ambiente, pre...

Deploy na Vercel: repositório, variáveis de ambiente, preview → production

ChatGPT Apps
Nível 7 , Lição 3
Disponível

1. Por que usar a Vercel para o ChatGPT App

Nas aulas anteriores, executamos o GiftGenius localmente e o conectamos ao ChatGPT via Dev Mode e túnel. Agora é hora de dar mais um passo rumo a um “produção de verdade” e levar o mesmo código para a Vercel.

Até aqui você já tem um aplicativo funcional, o GiftGenius (nosso App didático). Localmente, ele roda em Next.js 16 com um endpoint MCP (por exemplo, /api/mcp) e foi construído com base no ChatGPT Apps SDK Next.js Starter oficial.

Você até poderia seguir o caminho “alugo um VPS, instalo Node e nginx na mão e configuro tudo sozinho”, mas para Next.js isso é como escrever frontend com document.write em 2025. Funciona, mas você está claramente complicando a sua vida.

A Vercel é ótima para nós por vários motivos.

Em primeiro lugar, ela entende o Next.js de forma nativa: configura automaticamente build, SSR, estáticos, camada edge e funções serverless. Para o ChatGPT App isso é especialmente conveniente, porque o widget e o endpoint MCP são publicados com um clique e vivem na mesma infraestrutura.

Em segundo lugar, a Vercel oferece CI/CD out‑of‑the‑box: você conecta o repositório Git — e cada push cria um novo deployment imutável com URL exclusivo. Do branch main ele é considerado production; de outros branches — preview.

Em terceiro lugar, a Vercel tem uma ótima história de ambientes e segredos. Ela separa claramente variáveis de ambiente em Development, Preview e Production, armazena tudo criptografado e facilita o uso no Next.js. É exatamente o que o ChatGPT App precisa, onde chaves e a URL do servidor MCP devem mudar de acordo com o ambiente.

Em quarto lugar, a Vercel tem rollbacks práticos: se um novo release der ruim, você pode rapidamente promover o deployment anterior bem‑sucedido e restaurar o sistema. Isso reduz o “medo do deploy” e incentiva releases pequenos e frequentes.

E, por fim, a Vercel é a empresa que criou o Next.js. Eles ajustaram o Next.js para seus servidores, e seus servidores para o Next.js. Usando a Vercel você vai sentir como tudo funciona de forma suave e em poucos cliques. Garanto: você vai gostar.

2. Ponto de partida: estrutura do projeto GiftGenius

Pelo plano do curso, nosso GiftGenius vive em um único repositório. Há duas opções de organização, e ambas são válidas para a Vercel:

1) Monorepo com vários aplicativos — por exemplo:

giftgenius/
  apps/
    web/   # Next.js (widget + MCP)
    mcp/   # servidor MCP separado (se você o separou)

2) Um único projeto Next.js, no qual o widget e o MCP vivem juntos (é mais simples no início e é assim que o starter oficial é organizado):

giftgenius/
  app/
    page.tsx         # Widget
    api/
      mcp/route.ts   # MCP endpoint
  next.config.mjs
  package.json
  ...

Nas aulas do Módulo 2, você já clonou o Apps SDK Starter, instalou as dependências e rodou npm run dev. Agora, vamos supor que:

  • o projeto já esteja no Git (GitHub / GitLab / Bitbucket);
  • localmente você usa .env.local com chaves (OPENAI_API_KEY e outras);
  • o ChatGPT Dev Mode está conectado ao seu túnel.

Nossa tarefa é fazer com que o mesmo código seja criado e executado na Vercel, e que o ChatGPT possa acessar não o túnel, mas um domínio HTTPS estável no formato https://giftgenius.vercel.app.

3. Preparando o repositório para o deploy

Antes de clicar na Vercel em “New Project”, vale dar uma ajeitada no repositório. São passos simples, mas que economizam muito tempo depois.

Primeiro, certifique‑se de que .env.local e .vercel não sejam commitados. No .gitignore do Next.js Starter isso geralmente já está lá, mas confira:

node_modules
.next
.env.local
.vercel

.env.local é sua configuração local e segredos. Ele nunca deve ir para o Git, especialmente se tiver OPENAI_API_KEY ou chaves de banco. Na Vercel, vamos guardar os segredos separadamente na interface.

Em segundo lugar, dê uma olhada no package.json. Para a Vercel, são importantes os scripts corretos:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

A Vercel, por padrão, chamará npm run build (ou pnpm build, se você usa pnpm). Isso deve compilar o projeto sem erros.

Em terceiro lugar, garanta que a versão do Node esteja especificada e compatível com o Next.js 16. Nas release notes do Next.js 16, a versão mínima é 18.18.0. Na maioria dos casos, basta incluir no package.json:

{
  "engines": {
    "node": ">=18.18.0"
  }
}

A Vercel escolherá uma versão LTS do Node compatível com seu app.

Se tudo isso estiver feito, faça push do código mais recente no Git e siga para a Vercel.

4. Primeiro import do projeto na Vercel

Agora vamos para a interface web da Vercel. Se você ainda não tem conta, é a hora.

Você faz login na Vercel, clica em “New Project” e escolhe na lista o seu repositório giftgenius. Nessa etapa, a Vercel verifica o conteúdo do repo e quase sempre detecta sozinha que é um projeto Next.js, aplicando o preset correspondente.

Nas configurações do projeto, a Vercel vai sugerir:

  • Framework = Next.js;
  • Build Command = npm run build (ou pnpm build/yarn build);
  • Output Directory — padrão .next (não precisa alterar).

Para o primeiro deploy, você pode não definir as variáveis de ambiente imediatamente (vamos adicioná‑las em um passo separado). Clique em “Deploy” — a Vercel clona o repositório, instala dependências, executa npm run build e, se tudo der certo, cria o primeiro deployment com um endereço como https://giftgenius-xyz.vercel.app.

É importante entender uma coisa: cada deploy é imutável. Se você fizer push depois, será criado um novo deployment com uma nova URL, e o antigo permanecerá no histórico. O domínio de produção (por exemplo, giftgenius.vercel.app ou um domínio próprio) aponta para um deployment específico e pode ser alternado para trás ao fazer rollback.

Esquematicamente, fica assim:

flowchart LR
    A[Repositório GitHub
giftgenius] -->|git push| B[Build na Vercel] B --> C[Preview Deploy #1
URL única] B --> D[Preview Deploy #2
URL única] D --> E[Alias de produção
giftgenius.vercel.app]

O branch Git main geralmente é considerado o branch de produção; todo o resto — preview. Mas isso pode ser reconfigurado.

5. Variáveis de ambiente na Vercel

Agora seu primeiro deployment provavelmente não está muito funcional: falta OPENAI_API_KEY, o servidor MCP não acessa APIs externas etc. Hora de cuidar das variáveis de ambiente.

Na Vercel, as variáveis de ambiente ficam em Settings → Environment Variables. Ali também há a separação em três escopos: Development, Preview e Production.

Tabelinha para a sua referência mental:

Escopo Onde é usada Análogo local
Development vercel dev e desenvolvimento local via Vercel CLI .env.local
Preview todos os deploys de branches que não são o de produção staging / teste
Production deploys do branch de produção (geralmente main) “de produção” .env.prod

A diferença em relação ao .env.local é que a Vercel armazena os valores criptografados e os injeta automaticamente como process.env.MY_VAR no código do Next.js.

É muito importante entender o prefixo NEXT_PUBLIC_. Tudo que começa com NEXT_PUBLIC_ vai parar no bundle do navegador e ficará visível a qualquer usuário (é possível ver pelo DevTools). Isso é ótimo para configuração pública (NEXT_PUBLIC_ENV=preview, NEXT_PUBLIC_API_BASE_URL=https://giftgenius.vercel.app), mas é uma péssima ideia para chaves como OPENAI_API_KEY.

Para segredos, usamos nomes sem NEXT_PUBLIC_ e fazemos a leitura apenas no lado do servidor: em route handlers, ferramentas MCP etc.

6. Configurando env para o GiftGenius: exemplo

Vamos ver quais variáveis de ambiente são necessárias para o nosso GiftGenius didático.

Um conjunto mínimo pode ser assim:

  • OPENAI_API_KEY — chave para chamar modelos / cliente MCP;
  • APP_BASE_URL — URL base do app (https://giftgenius.vercel.app ou a URL de preview);
  • possivelmente, GIFTDATA_API_URL ou PRODUCTS_API_URL, se você tiver um catálogo externo.

No desenvolvimento local, isso fica em .env.local:

OPENAI_API_KEY=sk-local-...
APP_BASE_URL=http://localhost:3000
PRODUCTS_API_URL=https://dev-api.gifts.example.com

Na Vercel, vá em Settings → Environment Variables e adicione as mesmas chaves e valores, só que nos escopos apropriados.

Exemplo de como isso fica no código do endpoint MCP:

// app/api/mcp/route.ts
import { NextRequest } from 'next/server';

const apiKey = process.env.OPENAI_API_KEY!; // não faça isso sem validações em código real :)

export async function POST(req: NextRequest) {
  if (!apiKey) {
    return new Response('Missing OPENAI_API_KEY', { status: 500 });
  }
  // Chamada ao OpenAI ou a outro serviço com apiKey...
}

O widget pode usar APP_BASE_URL no lado do servidor, por exemplo, para construir links absolutos levando em conta o iframe do ChatGPT e a configuração de assetPrefix/basePath do starter.

Se ele precisar de uma URL pública do API (por exemplo, para window.fetch para o seu backend), você pode definir NEXT_PUBLIC_API_BASE_URL. Mas jamais NEXT_PUBLIC_OPENAI_API_KEY.

7. Deploys de preview: staging turbinado

Agora a parte mais legal: os deploys de preview. Quando você conectou o repositório Git, a Vercel passou a criar automaticamente um deployment de preview para cada push em um branch que não seja o de produção ou para cada Pull Request. Cada deployment tem uma URL única, algo como:

https://giftgenius-git-feature-new-layout-username.vercel.app

Esses deployments usam o escopo Preview para as variáveis de ambiente, então você pode definir, por exemplo:

# Ambiente de Preview na Vercel
APP_BASE_URL=https://giftgenius-staging.vercel.app
PRODUCTS_API_URL=https://staging-api.gifts.example.com

e não confundir isso com o production.

Do ponto de vista do ChatGPT Dev Mode, a URL de preview é a candidata ideal para staging. Nas configurações do seu Dev App, você pode trocar temporariamente o endpoint da URL do túnel para a URL de preview e observar como se comporta a versão já compilada do GiftGenius, mas ainda não o deployment de production.

Um padrão comum: para uma feature você cria o branch feature/smart-recommendations, faz push das alterações — a Vercel fornece o link de preview. Você vai ao Dev Mode, troca a URL para esse link, verifica os cenários com GPT (escolha de presentes, exibição de cards, chamadas de ferramentas MCP). Só quando tudo estiver ok, faz merge em main. O production segue sua vida tranquilamente.

Esquema mental do pipeline:

flowchart TD
    A[Dev local
localhost + túnel] --> B[git push
feature/*] B --> C[Preview Deploy
preview-URL] C --> D[ChatGPT Dev Mode
App → preview-URL] C --> E[Code review / testes] E --> F[Merge em main] F --> G[Production Deploy
prod-URL] G --> H[ChatGPT Prod App
App → prod-URL]

8. Deploy de produção e rollback

Quando você faz merge em main (ou outro branch que você escolheu como de produção), a Vercel cria um deployment de produção e atribui a ele o alias de produção: giftgenius.vercel.app ou seu próprio domínio.

Nesse momento, o ChatGPT Prod App (que você criará logo mais) deve estar configurado para a URL de produção. No Dev Mode, você continua experimentando com o túnel ou a URL de preview; usuários normais na loja do ChatGPT acessarão a produção.

A vantagem dos deployments imutáveis é que o rollback fica bem simples. Se o novo release foi problemático (por exemplo, uma ferramenta MCP falha com dados reais), você não precisa consertar o mundo às pressas no prod. Abra a lista de deployments na Vercel, escolha o último bem‑sucedido e clique em algo como “Promote to Production” — K8s e Lambda em algum lugar dão um jeito, e o seu domínio volta a apontar para a versão estável.

No CLI, isso também pode ser automatizado com comandos como vercel rollback, mas, para o nosso curso, basta entender a ideia: cada deployment é um artefato separado, e o alias de produção pode apontar para qualquer um deles.

9. Especificidades do Next.js 16 + MCP na Vercel

Para a Vercel, o seu endpoint MCP no Next.js é uma função serverless (ou edge function, se você configurou assim). Ela vive pouco: acorda quando chega a requisição, a processa e finaliza. Não dá para manter estado entre chamadas, a menos que você use um banco externo ou algum storage.

Isso é crítico para MCP: se você, por acaso, decidir guardar o histórico do diálogo em um array global let history = [] no route.ts, ele será zerado a cada cold start. Para armazenar estado é preciso usar um sistema externo (KV, Postgres etc.), mas isso fica para módulos futuros.

O segundo aspecto são os timeouts de execução. Nos planos gratuitos da Vercel, as funções serverless têm limite de tempo (na época da preparação deste material — cerca de 10 segundos no Hobby, mais no Pro). Para requisições de LLM e, especialmente, para cadeias de ferramentas MCP, isso pode ser pouco.

No Next.js 16, para route handlers você pode definir maxDuration para pedir explicitamente mais tempo à Vercel (dentro do limite do seu plano):

// app/api/mcp/route.ts
export const maxDuration = 60; // segundos; no Pro pode chegar a 300

export async function POST(req: Request) {
  // operação demorada: chamada ao OpenAI, banco externo etc.
}

Isso não é um botão mágico “faça o que quiser”, mas é a maneira correta de dizer à Vercel: “esta função pode levar mais tempo; não a finalize cedo demais, por favor”.

Por fim, não se esqueça das particularidades do iframe do ChatGPT. No Apps SDK Starter já estão configurados assetPrefix e basePath para que os estáticos e rotas funcionem corretamente dentro dos nested iframes de web-sandbox.oaiusercontent.com. Graças a isso, todas as requisições vão para o seu domínio, não para o sandbox. Ao fazer deploy na Vercel, essa config é mantida, então você tem o widget funcionando corretamente “de fábrica”.

10. Integração com o ChatGPT após o deploy

Embora isso esteja mais ligado aos módulos sobre Store e produção, a vida do app e a lógica de integração com o ChatGPT após o deploy são simples e se encaixam bem já agora.

Primeiro, você faz o deploy do GiftGenius na Vercel e obtém a URL de produção. Depois, no ChatGPT em Dev Mode, cria um App separado, por exemplo GiftGenius Prod, e nas configurações dele define essa URL como endpoint (mais precisamente, o endpoint MCP como https://giftgenius.vercel.app/api/mcp, conforme o guia do OpenAI Apps SDK Deploy).

Para desenvolvimento, você continua usando o Dev App apontando para o túnel ou a URL de preview. Para testar builds diários/semanais, você pode criar um Staging App, vinculando‑o a um preview alias estável. Como resultado, você terá um esquema em três camadas:

Dev App     → túnel local ou dev-URL (instável)
Staging App → URL de preview/staging estável na Vercel
Prod App    → URL de produção na Vercel

Para referência, vamos resumir em uma tabela:

O quê URL / deploy na Vercel Escopo na Vercel Quem acessa
Dev App túnel local / vercel dev Development você / equipe
Staging App preview alias estável Preview equipe / QA
Prod App giftgenius.vercel.app / domínio próprio Production usuários

É o mesmo modelo local / staging / prod de que falamos no início do módulo, agora vinculado à Vercel e aos ChatGPT Apps. Isso já é a arquitetura de um projeto profissional, não o localhost eterno.

11. Erros comuns ao fazer deploy na Vercel

Erro nº 1: segredos ficaram apenas no .env.local e não estão na Vercel.
Cenário muito comum: localmente tudo funciona, você clica confiante em “Deploy”, o app compila, mas as ferramentas MCP em produção retornam 500 com o texto “Missing OPENAI_API_KEY”. O motivo é simples: a Vercel não sabe do seu .env.local. É preciso cadastrar as mesmas variáveis nas configurações do projeto na Vercel (e nos escopos corretos: Preview, Production).

Erro nº 2: uso de NEXT_PUBLIC_ para dados sensíveis.
A vontade de “fazer funcionar de qualquer jeito” às vezes vence, e o dev coloca NEXT_PUBLIC_OPENAI_API_KEY para ter acesso à chave no código do cliente. O resultado é que a chave vai para o bundle de JS e fica acessível a qualquer usuário. Isso não é só má prática: é caminho direto para vazamento e bloqueio da chave. Todos os segredos — apenas sem o prefixo e apenas no lado do servidor.

Erro nº 3: ambientes inconsistentes entre local e Vercel.
Localmente você pode ter uma URL para produtos (http://localhost:4000), na Vercel — outra (https://api.gifts-staging.com) e na produção — uma terceira. Se você não mantiver uma lista organizada de variáveis de ambiente e não verificar que em Preview/Production estão preenchidas corretamente, é fácil acabar com o widget de produção chamando o backend de staging, e o de staging — o de produção. Disciplina simples ajuda: documente todas as variáveis necessárias e verifique cada ambiente.

Erro nº 4: ignorar limites de tempo de execução nos endpoints MCP.
No ambiente local, você pode esperar a resposta de um sistema externo lento por 30 segundos e não notar problemas. Na Vercel, a mesma função receberá timeout em 10–15 segundos, e o ChatGPT verá um erro. Se você não configurou maxDuration e não monitora o tempo de execução das ferramentas MCP, isso pode virar quedas aleatórias em produção.

Erro nº 5: tentar armazenar estado do MCP na memória da função serverless.
Às vezes dá muita vontade de guardar o histórico do diálogo ou um cache de recomendações em uma variável global let cache = {} diretamente no arquivo do route handler. No ambiente local, enquanto o dev server fica muito tempo de pé, isso pode até “funcionar”. Mas na Vercel cada função serverless vive pouco e frequentemente é recriada. O resultado é que parte das requisições “vê” um cache antigo, parte — um novo e parte — vazio. Isso gera bugs estranhos, difíceis de reproduzir. Para estado, use um banco externo ou um KV; no nível desta aula, é melhor considerar o endpoint MCP stateless.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION