← Blog

Os doze fatores, num servidor que é seu

Railyard

1 de junho de 2026 · 3 min de leitura

A metodologia twelve-factor app veio da equipe de engenharia inicial do Heroku, descrevendo as restrições que um app web precisa satisfazer para rodar bem em qualquer plataforma moderna. Ela sobreviveu à plataforma que a produziu, porque os doze fatores nunca foram realmente sobre o Heroku — são sobre o que torna um software portátil, escalável e operável, independente de quem é dono da máquina por baixo dele. Aqui está onde cada um deles de fato aparece, concretamente, numa plataforma construída em torno de servidores que você possui em vez de aluga.

I. Codebase. Um repositório, um deploy — git push, ou a mesma URL do Git colada no painel, reconstrói e refaz o deploy a cada push. Nada aqui é específico de quem é dono do servidor; é o mesmo workflow que o Heroku popularizou, rodando contra uma infraestrutura cujas chaves você tem.

II. Dependencies. Declaradas explicitamente, nunca assumidas a partir do host: requirements.txt, Gemfile, package.json, go.mod, composer.json, mix.exs são lidos diretamente, e nada sobre o ambiente de build ou execução é assumido como já instalado globalmente no sistema.

III. Config. Vive em Variables, ou é definida com railyard env:set my-app KEY=VALUE — nunca embutida na build. O mesmo artefato roda sem alteração desde uma branch de preview até a produção; um bug no staging ou é real ou não é, nunca um artefato do staging rodando um bundle diferente do da produção.

IV. Backing services. Um banco de dados, Redis, ou outro app no canvas é referenciado da mesma forma, seja local ou remoto: ${{postgres.RAILYARD_PRIVATE_URL}}, resolvido por ambiente. Troque o recurso de apoio e o código do app nunca precisa saber.

V. Build, release, run. Três estágios distintos, não um passo só borrado: um método de build (Dockerfile primeiro, se existir, depois Railpack, Nixpacks, ou buildpacks) produz um artefato; um comando de release (php artisan migrate --force, python manage.py migrate --no-input, mix ecto.migrate) roda uma vez contra a nova release antes do tráfego se mover; depois o estágio de execução de fato a inicia. Cada estágio pode falhar de forma independente, e falha, em vez de um único script fazer os três e esconder qual parte quebrou.

VI. Processes. Sem estado, e mais de um tipo compartilhando uma única build: web, worker, scheduler, beat — cada um iniciado com um comando diferente, cada um escalado de forma independente (railyard scale my-app worker=2). Um codebase, vários papéis, nunca vários codebases para manter sincronizados.

VII. Port binding. O app vincula a $PORT ele mesmo e exporta HTTP como um serviço — não é injetado num container de runtime por magia. Um binário em Go, um processo Rails, uma release Elixir compilada: todos vinculam ao mesmo contrato $PORT, que é todo o motivo pelo qual o mesmo método de build funciona entre linguagens completamente diferentes.

VIII. Concurrency. Escale para fora via o modelo de processos, não fazendo um processo fazer mais: web=3 worker=2 são duas dimensões escaladas de forma independente da mesma build, não um exercício de ajuste de contagem de threads dentro de um único processo.

IX. Disposability. Início rápido, encerramento gracioso, e uma release nova só recebe tráfego depois que o container dela de fato responde — o antigo continua servindo até o novo provar que está pronto, então um deploy ruim nunca abre uma janela onde nada está no ar.

X. Dev/prod parity. A regra única que aparece, literalmente, na própria lógica de detecção de cada framework nessa plataforma: a mesma build roda sem alteração desde o primeiro push de um desenvolvedor até o staging e a produção. Nenhum “Dockerfile de produção” separado, nenhum rebuild específico de ambiente — paridade não é uma meta para perseguir, é o único caminho que existe.

XI. Logs as event streams. O app só imprime para stdout/stderr; ele nunca gerencia seus próprios arquivos de log. O que quer que o container imprima é o que aparece em tempo real, o que é buscável depois, e o que é enviado para um drain — o trabalho do app termina em imprimir, exatamente como sempre deveria ter sido.

XII. Admin processes. Tarefas pontuais rodam exatamente no mesmo ambiente que o app no ar, não um console mantido separadamente: railyard run my-app -- bin/rails db:migrate inicia um container novo a partir da release atual — a própria CLI toma de empréstimo o nome que o Heroku deu à mesma ideia (heroku run), porque a ideia já estava certa.

O ponto real de revisitar isso agora

Nenhuma dessas doze regras exige alugar infraestrutura de quem as escreveu. Elas descrevem como construir software que não se importa com quem é dono da máquina em que roda — que é exatamente a propriedade que torna um app portátil para fora de qualquer plataforma desde o início, incluindo essa aqui.

Referência completa: Build methods, Variables and secrets, CLI docs.

Veja um app twelve-factor sendo implantado em tempo real.

Faça push de um repositório que já segue essas regras — nada nelas muda num servidor que é seu.

Plano grátis, sem cartão, e 14 dias de Pro para cada equipe nova. Um preço fixo por equipe.