docs
Guias

Melhores Práticas

Configurações recomendadas para garantir deploy seguro, rápido e estável na Veloz.

Configurações recomendadas para deploy na Veloz. A maioria é detectada automaticamente — quando algo estiver faltando, a CLI avisa antes do deploy.


Next.js — não use output: "standalone" na Veloz

Na Veloz, o mesmo container serve tanto o servidor SSR quanto os arquivos estáticos (public/ e .next/static/). O modo standalone foi projetado para ambientes que separam a entrega de assets estáticos (CDN) do servidor Node.js — e exige que você copie manualmente esses diretórios no Dockerfile, o que complica o setup sem necessidade.

Deixe o output padrão (ou remova o campo caso tenha adicionado seguindo outras plataformas):

// next.config.ts
import type { NextConfig } from "next";
 
const config: NextConfig = {
  // sem output: "standalone" — a Veloz serve os estáticos do mesmo container
};
 
export default config;

Se você migrou de Vercel ou Railway e tinha output: "standalone" configurado, remova essa linha.


Prisma — prisma generate no build + migrations no pre-start

O Prisma Client precisa ser gerado antes do app iniciar. Sem isso, o app vai crashar com PrismaClientInitializationError.

Opção 1 — postinstall (recomendado para projetos simples):

// package.json
{
  "scripts": {
    "postinstall": "prisma generate",
    "build": "next build"
  }
}

Opção 2 — dentro do build (recomendado para monorepos com Turborepo):

{
  "scripts": {
    "build": "prisma generate && next build"
  }
}

Opção 3 — via veloz.json:

{
  "services": {
    ".": {
      "build": {
        "command": "prisma generate && npm run build"
      }
    }
  }
}

Se você usa Turborepo e o prisma generate já faz parte do pipeline de build, pode ignorar o aviso da CLI.

Migrations automáticas com preStartCommand

Para rodar migrations automaticamente em cada deploy, use o preStartCommand:

{
  "services": {
    ".": {
      "runtime": {
        "command": "node server.js",
        "preStartCommand": "npx prisma migrate deploy"
      }
    }
  }
}

Ou via CLI:

veloz config set --pre-start "npx prisma migrate deploy"

O preStartCommand roda antes do serviço iniciar, no mesmo ambiente (mesma imagem, mesmas env vars). Se a migration falhar, o deploy é interrompido — o serviço continua na versão anterior.


Variáveis de ambiente

Nunca commite o arquivo .env — use sempre o dashboard ou a CLI para definir variáveis em produção.

# Definir variáveis antes do deploy
veloz env set DATABASE_URL=postgres://...
veloz env set JWT_SECRET=...
veloz env set RESEND_API_KEY=re_...

Certifique-se que o .env está no .gitignore:

# .gitignore
.env
.env.local
.env*.local

Porta do servidor

A Veloz usa a variável de ambiente PORT para rotear o tráfego. Seu app deve escutar na porta definida por PORT, com fallback para 3000.

// ✅ correto
const port = process.env.PORT ?? 3000;
app.listen(port);
 
// ❌ evite porta hardcoded
app.listen(8080);

Se seu app usa porta diferente de 3000, configure no veloz.json:

{
  "services": {
    ".": {
      "runtime": { "port": 8080 }
    }
  }
}

SvelteKit — adapter-node

O adapter-auto e adapters de plataformas específicas (Vercel, Netlify, Cloudflare) não funcionam na Veloz. Use @sveltejs/adapter-node:

npm install -D @sveltejs/adapter-node
// svelte.config.js
import adapter from "@sveltejs/adapter-node";
 
export default {
  kit: { adapter: adapter() },
};

bcrypt — use bcryptjs

O bcrypt compila código nativo e pode falhar no build dependendo do ambiente. O bcryptjs é equivalente em pure JavaScript:

npm uninstall bcrypt
npm install bcryptjs
npm install -D @types/bcryptjs
import bcrypt from "bcryptjs"; // mesma API

Nixpacks vs Dockerfile próprio

A Veloz usa nixpacks por padrão para gerar um Dockerfile automaticamente a partir do seu código. Isso funciona bem para projetos simples ou quando funciona de primeira.

Para projetos com requisitos complexos — dependências nativas, multi-stage builds, ou ambientes de produção críticos — é preferível escrever seu próprio Dockerfile. Builds com Dockerfile são mais confiáveis e reproduzíveis.

{
  "build": {
    "method": "dockerfile",
    "dockerfile": "Dockerfile",
    "context": "."
  }
}

Quando usar Dockerfile:

  • O build com nixpacks falhou ou deu resultado inesperado
  • Seu projeto precisa de dependências do sistema complexas
  • Você precisa de multi-stage build para otimizar tamanho da imagem
  • É um ambiente de produção onde reprodutibilidade importa

Quando nixpacks é suficiente:

  • Side projects e protótipos
  • Projetos Node.js simples sem dependências nativas
  • Quando funcionou de primeira sem problemas

nixpacks.toml — preservar comandos padrão com "..."

Se você personaliza fases no nixpacks.toml, use "..." para incluir os comandos padrão da fase além dos seus:

# ✅ correto — executa os comandos padrão + o seu
[phases.build]
cmds = ["...", "prisma generate"]
 
# ❌ errado — substitui TODOS os comandos padrão (o build não vai funcionar)
[phases.build]
cmds = ["prisma generate"]

Dockerfile — lockfile correto no COPY

Se você tem um Dockerfile e usa Bun, use glob para copiar apenas o lockfile que existe:

# ✅ correto
COPY package.json bun.lock* ./
 
# ❌ errado — vai falhar se um dos dois não existir
COPY package.json bun.lockb bun.lock ./

Comando start obrigatório

A Veloz precisa saber como iniciar seu app. Se você usa um framework com start command automático (Next.js, Nuxt, etc.) não precisa fazer nada. Para apps genéricos:

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  }
}

Ou configure via CLI:

veloz config set --start-command "node dist/index.js"

packageManager consistente com o lockfile

Se você declara o packageManager no package.json, certifique-se de que o lockfile correspondente existe:

// package.json
{
  "packageManager": "[email protected]" // precisa de pnpm-lock.yaml
}

Se estiver migrando de package manager, remova o campo packageManager ou gere o lockfile correto antes do deploy.


Django — use gunicorn em produção

O servidor de desenvolvimento do Django (runserver) não deve ser usado em produção. Instale o gunicorn:

# requirements.txt
gunicorn
# start command
gunicorn myproject.wsgi --bind 0.0.0.0:$PORT

Go — CGO e binário estático

Por padrão, Go compila com CGO habilitado que precisa de glibc. Para builds mais confiáveis:

# nixpacks.toml
[phases.build]
cmds = ["CGO_ENABLED=0 go build -o server ."]

Ou se precisa de CGO, inclua gcc nos pacotes:

[phases.setup]
nixPkgs = ["go", "gcc"]

PHP — use versão 8.3+

PHP 8.1 e 8.2 podem falhar no Nixpacks. Use 8.3+ com nixpacks.toml:

[phases.setup]
nixPkgs = ["php83", "php83Packages.composer"]
 
[start]
cmd = "php -S 0.0.0.0:3000 -t public"

Elixir — nixpacks.toml obrigatório

A detecção automática do Elixir pode falhar. Configure manualmente:

[phases.setup]
nixPkgs = ["elixir", "erlang", "gcc"]
 
[phases.build]
cmds = ["mix deps.get", "mix release"]
 
[start]
cmd = "_build/prod/rel/my_app/bin/my_app start"

Deploy cancelamento — Ctrl+C

Se você iniciou um deploy por engano ou precisa parar, pressione Ctrl+C durante o build. O deploy é cancelado e o serviço permanece na versão anterior.


Resumo rápido

Situação Recomendação
Next.js vindo de Vercel/Railway Remova output: "standalone" — não é necessário na Veloz
Projeto com Prisma prisma generate no build, migrations no preStartCommand
Arquivo .env no projeto Adicione ao .gitignore, use veloz env set
SvelteKit Use @sveltejs/adapter-node
Porta customizada Configure com veloz config set --port <porta>
bcrypt Migre para bcryptjs
Django Use gunicorn no start command
Go com CGO CGO_ENABLED=0 ou inclua gcc no nixpacks.toml
PHP Use 8.3+ com nixpacks.toml
Elixir nixpacks.toml obrigatório (elixir + erlang + gcc)
Deploy errado Ctrl+C cancela — serviço fica na versão anterior

Dúvidas? Consulte o Troubleshooting ou abra um ticket no Discord.