Migrar para a Zenifra

Migrar da Vercel para a Zenifra

Este guia mostra, campo a campo, onde encontrar cada configuração de um projeto no painel da Vercel e onde informar o mesmo valor no console da Zenifra. Ele cobre aplicações Next.js, sites estáticos e SPAs (Vite, React, Vue, Astro) e APIs feitas com Vercel Functions. Para o roteiro geral, com cópia de dados e troca de DNS, veja Migrar para a Zenifra.

Mantenha o projeto da Vercel no ar enquanto você sobe e valida a aplicação na Zenifra. Só remova o projeto da Vercel depois de trocar o DNS.

O que muda de uma plataforma para a outra

Na Vercel, o código do servidor roda em funções que sobem sob demanda e escalam a zero. Na Zenifra, a aplicação é um servidor contínuo: um processo que fica ligado, reaproveita conexões com o banco e não tem partida a frio por requisição.

Na VercelNa Zenifra
ProjetoProjeto HTTP
Next.js com funções por rotaUm servidor next start com todas as rotas
Vercel Functions na pasta api/Rotas de um servidor HTTP (Express, Fastify, Hono etc.)
Cron Jobs do vercel.jsonJobs agendados
Preview DeploymentsAmbientes de Preview
Deployment ProtectionControle de acesso por IP ou proteção na própria aplicação
Postgres e KV do Marketplace (Neon, Upstash etc.)PostgreSQL gerenciado e Cache gerenciado
Vercel BlobArmazém

1. Copie as configurações na Vercel

No painel da Vercel, abra o projeto e clique em Settings.

Build and Deployment

Em Settings › Build and Deployment, anote os campos da seção Build & Development Settings e as seções seguintes:

Campo na VercelPara que serve
Framework PresetFramework detectado, como Next.js, Vite ou Other
Build CommandComando de build. Se o Override está desligado, é o padrão do framework, normalmente npm run build
Output DirectoryPasta publicada em sites estáticos, como dist ou build
Install CommandInstalação de dependências, como npm install ou pnpm install
Root DirectoryPasta da aplicação dentro do repositório (monorepo)
Node.js VersionVersão principal do Node.js, como 22.x ou 24.x

Se o package.json tem engines.node, essa versão vale mais que o campo Node.js Version: use a do package.json.

Branch de produção e domínios

  • Em Settings › Environments › Production, a seção Branch Tracking mostra a branch publicada em produção, normalmente main.
  • Em Settings › Domains, anote todos os domínios do projeto.
  • Em Settings › Git, confira o repositório conectado.

Se os seus domínios usam os nameservers da Vercel (ns1.vercel-dns.com e ns2.vercel-dns.com), copie também todos os registros DNS, como MX e TXT de e-mail, antes de mudar os nameservers. Sem isso, o e-mail do domínio pode parar.

Environment Variables

Em Settings › Environment Variables, cada variável tem um Value, um Type e as environments em que vale: Production, Preview ou Development. Copie as de Production.

O jeito mais rápido é exportar pela CLI da Vercel, na pasta do projeto:

vercel env pull .env.production --environment=production

Sem --environment=production, a CLI baixa as variáveis de Development. Confira o arquivo gerado antes de usar.

Variáveis do tipo Secret (antes chamadas de Sensitive) não podem ser lidas depois de salvas, nem no painel nem pela CLI. Pegue esses valores na origem, como o painel do provedor de pagamentos ou o gerenciador de senhas da equipe, ou gere valores novos.

Confira também as variáveis compartilhadas do time, em Team Settings, que chegam ao projeto sem aparecer na lista dele.

vercel.json

Se o repositório tem um vercel.json (ou vercel.ts), anote as chaves abaixo. A Zenifra não lê esse arquivo, então cada uma precisa de um equivalente:

ChaveO que fazer na Zenifra
buildCommand, installCommand, outputDirectoryUsar os valores nos comandos do projeto; veja a etapa 2
rewrites, redirects, headersMover para o next.config ou para o servidor de arquivos; veja Rewrites, redirects e headers
cleanUrls, trailingSlashMesmo caminho dos redirects
cronsCriar Jobs agendados
functions (maxDuration, memory)Não se aplica: a aplicação é um servidor contínuo e os recursos vêm do plano
regionsNão se aplica: a Zenifra roda no Brasil
imagesUsar images no next.config

2. Crie o projeto na Zenifra

No console, clique em + Criar projeto, escolha Aplicação HTTP e o plano. Em Configurações Avançadas, escolha Repositório Git em Origem do Projeto, o Provedor Git GitHub (ou Forgejo), o mesmo repositório e a branch de produção. Depois preencha os campos conforme o tipo de projeto.

Next.js

Na VercelNo console da Zenifra
Node.js VersionRuntime Node.js e Versão igual (20, 22, 24 ou 26)
Root DirectoryDiretório raiz. Deixe . se o campo estava vazio
Install CommandNão tem campo: a Zenifra instala com npm ci
Build CommandComando Build: npm run build
—Comando Start: npx next start -H 0.0.0.0 -p 3000
—Porta: 3000
Environment VariablesVariáveis de Ambiente, incluindo as NEXT_PUBLIC_*

Renderização no servidor, rotas de API, Server Actions, middleware (ou proxy.ts no Next.js 16) e otimização de imagens com next/image funcionam com next start, sem adaptador. Veja o guia completo de Next.js.

Site estático ou SPA (Vite, React, Vue, Angular, Astro)

Na VercelNo console da Zenifra
Node.js VersionRuntime Node.js e Versão igual
Build CommandComando Build, como npm run build
Output DirectoryPasta usada no Comando Start
—Comando Start: npx serve -s dist -l tcp://0.0.0.0:3000, trocando dist pelo Output Directory
—Porta: 3000

Adicione o serve às dependências com npm install serve. Em sites com várias páginas HTML, como Astro, remova o -s. Para gastar menos, publique com NGINX no plano Static; veja Sites estáticos e SPAs.

Vercel Functions fora do Next.js

Em projetos que não são Next.js, cada arquivo da pasta api/ vira uma função na Vercel. Na Zenifra, essas funções precisam virar rotas de um servidor HTTP que fica ligado. Um exemplo com Express:

server.js
import express from 'express'
import hello from './api/hello.js'

const app = express()
app.use(express.json())

// Cada arquivo de api/ vira uma rota
app.all('/api/hello', (req, res) => hello(req, res))

app.listen(process.env.PORT || 3000, '0.0.0.0')

Funções no formato handler(req, res) costumam funcionar sem mudanças no Express. Funções que exportam GET ou fetch com Request e Response da Web combinam melhor com Hono. Se o projeto também tem um frontend estático, sirva a pasta de build pelo mesmo servidor, com express.static, ou crie dois projetos: um para a API e outro para o site.

Configure Comando Start node server.js, Porta 3000 e a variável PORT=3000.

Install Command com pnpm, Yarn ou Bun

A Zenifra instala dependências Node.js com npm ci e precisa de um package-lock.json versionado. Se a Vercel usa pnpm ou Yarn, gere e versione um package-lock.json antes de migrar, ou publique como Imagem OCI. Projetos com Bun podem usar o Runtime Bun, que instala com bun install --frozen-lockfile. Veja Runtimes.

3. Ajuste o que muda entre as plataformas

Variáveis da Vercel

Variáveis criadas pela Vercel, como VERCEL_URL, VERCEL_ENV, VERCEL_PROJECT_PRODUCTION_URL e VERCEL_GIT_COMMIT_SHA, não existem na Zenifra. Procure no código e troque por variáveis suas:

grep -rn "VERCEL_" --include=*.{js,ts,tsx,jsx,mjs} .

Por exemplo, troque VERCEL_URL por uma variável APP_URL com a URL do projeto na Zenifra ou o seu domínio. Lembre que VERCEL_URL não tinha https://; confira se o código adicionava o protocolo.

Variáveis na build

Na Zenifra, as variáveis do projeto ficam disponíveis na build, então NEXT_PUBLIC_* e VITE_* funcionam como na Vercel. Depois de alterar uma delas, faça uma nova publicação, porque o valor fica gravado no JavaScript. Veja Variáveis durante o build.

Rewrites, redirects e headers

  • Next.js: mova rewrites, redirects e headers do vercel.json para as funções de mesmo nome no next.config. Nos redirects, permanent: true continua gerando 308.
  • Site estático com serve: o -s já resolve o rewrite de SPA para index.html. Para outras regras, crie um serve.json dentro da pasta publicada, com rewrites, redirects e headers.
  • Site estático com NGINX: use rewrite, return 301 e add_header no nginx.conf. Veja o exemplo em Sites estáticos e SPAs.

Cron Jobs

Na Vercel, um Cron Job faz uma requisição GET para uma rota da sua aplicação, com o segredo CRON_SECRET no header Authorization. Na Zenifra, um Job agendado executa um comando e termina. Para manter a rota que você já tem, crie um script que chama a rota:

scripts/cron.mjs
const res = await fetch(process.env.CRON_URL, {
  headers: { authorization: `Bearer ${process.env.CRON_SECRET}` },
})
if (!res.ok) process.exit(1)

Crie um Job agendado com Origem da tarefa Repositório GitHub, Runtime Node.js, Comando da tarefa node scripts/cron.mjs e as variáveis CRON_URL (a URL completa da rota) e CRON_SECRET. A Expressão cron pode ser a mesma do vercel.json: as duas plataformas usam UTC.

Se a tarefa não depende da aplicação, rode a lógica direto no script do Job, sem passar pela rota.

Edge Runtime

Rotas com export const runtime = 'edge' rodam no mesmo servidor Node.js na Zenifra. Remova essa linha: o próprio Next.js recomenda o runtime Node.js, e as versões recentes deixaram de aceitar edge.

Cache do Next.js com várias instâncias

O ISR e o cache de dados do Next.js ficam no disco de cada instância. Com uma instância, funcionam como esperado. Com mais de uma, cada instância tem o próprio cache e revalidatePath ou revalidateTag só afetam a instância que recebeu a chamada. Se isso importa, use uma instância ou configure um cacheHandler compartilhado com o cache gerenciado. Veja Cache do Next.js e várias instâncias.

Arquivos enviados por usuários

Na Zenifra, o disco da instância é apagado a cada publicação, como na Vercel. Se a aplicação usa o Vercel Blob, migre os arquivos para o Armazém, que é compatível com S3, ou mantenha o Blob durante a transição.

4. Migre bancos e serviços

Os bancos do Marketplace da Vercel são do provedor de origem, como Neon, Supabase ou Upstash. Exporte os dados direto nele:

OrigemDestino na ZenifraComo migrar
Postgres (Neon, Supabase, Prisma Postgres)PostgreSQL gerenciadopg_dump e pg_restore; veja Migrar o banco de dados
KV / Redis (Upstash)Cache gerenciado ou Chave-ValorDados de cache podem ser recriados pela aplicação
Vercel BlobArmazémBaixe os arquivos e envie com a AWS CLI ou o SDK S3; veja Conectar aplicações

Crie os bancos antes da aplicação e cadastre as novas URLs de conexão, como DATABASE_URL, nas variáveis do projeto. A conexão com o PostgreSQL da Zenifra exige TLS.

5. Valide e troque o DNS

  1. Abra a URL *.clients.zenifra.com do projeto e teste login, páginas principais, rotas de API, formulários e webhooks.
  2. Confira em Logs de build e nos logs da aplicação se não há erros.
  3. Atualize os webhooks externos (pagamentos, autenticação, e-mail) e as URLs de callback de OAuth para o novo endereço.
  4. Siga o checklist do dia da troca: reduza o TTL do DNS, faça a cópia final dos dados, adicione o domínio na Zenifra e atualize o DNS.
  5. Mantenha o projeto da Vercel ligado por alguns dias para rollback e só então o remova.

Problemas comuns

SintomaCausa provávelCorreção
npm ci falha na buildProjeto usa pnpm ou Yarn, sem package-lock.jsonGere e versione um package-lock.json ou use o runtime Bun, se for o caso
Rota /api/... retorna 404Função da pasta api/ sem servidorRegistre a rota no servidor HTTP; veja Vercel Functions fora do Next.js
URL pública não respondeServidor escutando em localhost ou porta diferenteEscute em 0.0.0.0 e use a mesma porta no campo Porta
Links e e-mails apontam para vercel.appCódigo usa VERCEL_URLTroque por uma variável própria, como APP_URL
Redirect do vercel.json parouA Zenifra não lê o vercel.jsonMova a regra para o next.config, serve.json ou nginx.conf
Rota recarregada retorna 404 em SPAFalta o fallback para index.htmlUse serve -s ou try_files no NGINX
Cron não executaCron Jobs do vercel.json não são lidosCrie um Job agendado

Precisa de ajuda?

Escreva para [email protected] com os campos que você copiou da Vercel ou fale pelo WhatsApp +55 (11) 5199-3013.

Última atualização em

Nessa página