upuai.toml
Configure build, release phase (migrations) e deploy diretamente no repo do seu app. Versionado, revisado em PR. Equivalente a Procfile (Heroku), fly.toml (Fly.io), railway.toml (Railway), netlify.toml (Netlify).
O que é
upuai.toml é um arquivo de configuração declarativa que vive na raiz do rootDirectory do seu service no monorepo (ex: apps/api/upuai.toml). Permite declarar como o Upuai Cloud builda, faz release phase (rodar migrations antes do rollout) e inicia seu app — sem precisar mexer na UI.
Quick start
Para um app Node + Prisma rodando migrations automáticas a cada deploy, copie o snippet abaixo para apps/api/upuai.toml (ou upuai.toml na raiz, em single-package). Próximo deploy roda automaticamente.
#:schema https://upuai.com.br/schemas/upuai-toml-v1.json
[deploy]
releaseCommand = "pnpm exec prisma migrate deploy"Schema v1 completo
Todas as keys são opcionais. Validação .strict() rejeita keys desconhecidas com erro explícito.
#:schema https://upuai.com.br/schemas/upuai-toml-v1.json
[build]
builder = "railpack" # default; outro valor: "dockerfile"
buildCommand = "pnpm build" # opcional, override do railpack
dockerfilePath = "Dockerfile" # só pra builder = "dockerfile"
[deploy]
startCommand = "node dist/server.js"
releaseCommand = "pnpm exec prisma migrate deploy"
releaseTimeoutSeconds = 300 # default 300s, max 1800s
healthCheckPath = "/health"| Key | Tipo | Descrição |
|---|---|---|
| build.builder | "railpack" | "dockerfile" | Build method. Railpack auto-detecta stack; dockerfile usa o Dockerfile do repo. |
| build.buildCommand | string | Override do comando de build do railpack. |
| build.dockerfilePath | string | Path do Dockerfile (relativo ao rootDirectory). Só pra builder=dockerfile. |
| deploy.startCommand | string | Comando que inicia o app (ex: node dist/server.js). |
| deploy.releaseCommand | string | Release phase: roda em Job efêmero ANTES do rollout (mesma imagem + env vars). Falha bloqueia traffic shift; pods velhos continuam servindo. Tipicamente usado pra migrations de DB. Idempotência é responsabilidade do comando. |
| deploy.releaseTimeoutSeconds | 10..1800 | Timeout do release Job em segundos. Default 300. |
| deploy.healthCheckPath | string | Endpoint HTTP que K8s usa pra readiness. Default vem do framework detectado (NestJS=/health, Spring=/actuator/health, Rails=/up). |
Processos (Procfile App)
Declare múltiplos processos (web + worker + release + clock) a partir de um único repositório/build, no estilo Procfile do Heroku. Um push builda a imagem uma vez e roda N processos compartilhando essa imagem — cada um com seu próprio comando, réplicas e recursos. Variáveis de ambiente são compartilhadas por todos os processos (paridade Heroku config vars). Gerencie com `upuai ps`, `upuai scale web=2 worker=1` / `upuai logs --process worker` por processo, ou pela aba Processos no dashboard.
#:schema https://upuai.com.br/schemas/upuai-toml-v1.json
# 1 push → 1 build → N processos compartilhando a imagem (web + worker + ...).
[processes.web]
command = "bundle exec puma"
[processes.worker]
command = "bundle exec sidekiq"
type = "worker" # opcional; inferido do nome (web→web, worker→worker, clock/cron→clock)
instances = 2 # opcional; default 1
[processes.release]
command = "bundle exec rails db:migrate"
type = "release"Release Command por framework
Lista curated de commands recomendados. Explicit, sem mágica — copie pro seu upuai.toml.
| Stack | releaseCommand |
|---|---|
| Prisma (Node monorepo pnpm) | pnpm exec prisma migrate deploy |
| Prisma (single-package) | npx prisma migrate deploy |
| Drizzle | pnpm exec drizzle-kit migrate |
| TypeORM | pnpm typeorm migration:run |
| Knex | pnpm knex migrate:latest |
| Sequelize | pnpm sequelize db:migrate |
| Django | python manage.py migrate --noinput |
| Alembic (SQLAlchemy) | alembic upgrade head |
| Rails (Active Record) | bundle exec rails db:migrate |
| Laravel | php artisan migrate --force |
| Phoenix / Ecto (Elixir) | mix ecto.migrate |
| golang-migrate (Go) | migrate -path migrations -database $DATABASE_URL up |
| atlas (Go) | atlas migrate apply --url $DATABASE_URL |
Monorepo
Cada service tem seu próprio rootDirectory — coloque o upuai.toml em <rootDirectory>/upuai.toml. O rootDirectory é a working directory dos commands releaseCommand e startCommand: eles rodam como se você tivesse feito cd <rootDirectory> antes — sem precisar de pnpm --filter, cd, ou --prefix no command. Services que não precisam de release phase / build customizado simplesmente não criam o arquivo. Ausência = nenhum override.
my-monorepo/
├── apps/
│ ├── api/
│ │ ├── upuai.toml # service "api" — releaseCommand pra migrations
│ │ └── src/
│ ├── web/
│ │ └── src/ # service "web" — sem upuai.toml (não precisa)
│ └── landing/
│ └── src/ # service "landing" — sem upuai.toml
└── pnpm-workspace.yamlPrecedência
Quando o mesmo campo aparece em mais de uma fonte, esta é a ordem de prioridade aplicada pelo Upuai.
- 1
UI (Service Settings)
Vence sempre. Use para override operacional sem precisar de PR (ex: aumentar timeout em incident).
- 2
upuai.toml
Config canonical, versionada, revisada em PR.
- 3
Procfile release: line
Legacy compat Heroku-style. Continua suportado.
VS Code autocomplete
Adicione a primeira linha apontando para o JSON Schema público. Com a extensão Even Better TOML (tamasfe.even-better-toml), você ganha autocomplete e validação inline.
#:schema https://upuai.com.br/schemas/upuai-toml-v1.json
[deploy]
releaseCommand = "..."Versioning
Schema segue SemVer. Mudanças backward-compat (novas keys opcionais) entram como v1.x sem mudar a URL. Breaking changes só num eventual v2 com janela mínima de 6 meses.
v1.x (atual)
Novas keys são opcionais e backward-compat. URL do #:schema continua a mesma.
v2 (futuro)
Breaking changes. URL muda pra upuai-toml-v2.json. Janela de transição mínima de 6 meses com aviso prévio.
FAQ
Perguntas frequentes sobre upuai.toml.
E se o meu repo já tem Procfile?
Continua funcionando. Procfile release: ... é legacy compat. Recomendamos migrar pro upuai.toml pra ganhar mais opções (timeout, health check, etc), mas não é obrigatório.
Como override sem deletar do repo?
Edite o campo na UI (Service Settings → Build & Deploy). UI override sempre vence o toml. Útil pra casos transitórios (incident, debug). v1.1 vai ter botão "Reset to upuai.toml" no painel do service pra limpar override sem deletar valor.
TOML é case-sensitive?
Sim. releaseCommand é diferente de ReleaseCommand.
Posso ter configs diferentes por ambiente (production/staging)?
Não em v1. upuai.toml é por service+rootDirectory, não por environment. Para config por env, use UI Service Settings ou env vars (ex: RELEASE_CMD_PROD, RELEASE_CMD_STAGING e um wrapper script).
Por que não auto-detectam o framework?
Heroku/Railway/Fly não auto-detectam ORM porque há centenas de migration tools (Prisma, Drizzle, TypeORM, Django, Alembic, Rails, Laravel, Flyway, golang-migrate, atlas, etc). Cada um com configurações específicas. Heurística que tenta cobrir isso quebra mais do que conserta. Explicit é o estado-da-arte — você declara o comando, a plataforma roda. Mesma filosofia do web: no Procfile.
Roadmap de v1.1+?
v1.1: [deploy] resources (cpu/memory/instances). v1.2: [networking].egress — declarar allowlist no repo. v1.3: UI editor inline pro arquivo. v1.4: restartPolicy, sleepApplication, autoDeploy. v1.5: [env] block — variáveis NÃO-secret commitáveis (LOG_LEVEL, NODE_ENV). v2: cronSchedule, podSecurityContext, multi-service array.
Recursos
Links para o JSON Schema, CLI e outras referências.