Rush CMS: um CMS headless multi-tenant que serve agências inteiras de uma única plataforma
SaaS Próprio
Developer tools, agências e múltiplos sites
Arquitetura, desenvolvimento, infraestrutura e operação
Produção Contínua desde 2025
O Rush CMS é meu SaaS: um CMS headless multi-tenant construído em Laravel 12 e Filament 4 para quem gerencia muitos sites ao mesmo tempoL agências e operações com dezenas de domínios sob o mesmo teto. Em vez de manter 50 instalações separadas de WordPress, uma única instância Laravel serve todos os clientes com isolamento de dados, cada um com seu conteúdo, seus usuários, suas permissões e sua API.
Diferente do resto do meu portfólio, este não é um projeto de cliente. É um produto que eu arquitetei, construí e mantenho sozinho, de ponta a ponta: do modelo de dados à infraestrutura, do painel administrativo à camada de API, do isolamento de tenant ao pipeline de 603 testes. É a peça onde minhas decisões de engenharia aparecem sem intermediário, porque cada uma foi minha.
E ele já está em produção. O próprio site que você está lendo, o rafhael.pro, roda em Rush CMS. Uma padaria com cardápio digital completo também. Casos de uso radicalmente diferentes servidos pela mesma base, que é exatamente o ponto de um CMS multi-tenant eficiente. O produto vive em rushcms.com.
O problema que o Rush resolve
Quem mantém muitos sites pequenos e médios conhece a dor: cada site vira uma instância separada de WordPress (ou similar), com sua própria atualização, seu próprio backup, sua própria superfície de ataque, sua própria conta de hospedagem. Dez sites viram dez sistemas para manter. Cinquenta viram um pesadelo operacional.
A alternativa óbvia, "um WordPress multisite", resolve parte do problema e cria outros: acoplamento entre sites, plugins que quebram todo mundo de uma vez, e um modelo de conteúdo preso a "posts e páginas" que não cabe em quem precisa de estruturas de dados próprias. Outro motivo: eu detesto ter que mexer com Wordpress, quando preciso muito, tenho que usar Sage para sofrer mentalmente menos.
Eu queria outra coisa: uma plataforma onde adicionar um novo site fosse adicionar um tenant, não subir um servidor. Onde o modelo de conteúdo fosse definido por quem usa, não imposto pela ferramenta. E onde a performance de entrega não dependesse de cache improvisado em cima de um sistema lento por natureza.
"Ah, mas e o Strapi? Existem diversas soluções no mercado", sim existe, e nenhuma me atendeu da forma que eu precisava - e queria. i18n first, multi-tenant isolado de fábrica, collections com databases, etc.
As decisões de arquitetura
Este é o coração desse case, porque o Rush CMS é, antes de tudo, um conjunto de decisões técnicas conscientes. Cada uma tem um porquê.
Multi-tenancy com isolamento real via global scopes
Os tenants são 100% isolados, e não existe um super-admin que enxerga os dados de todos os clientes, essa foi uma decisão deliberada de segurança e privacidade. O isolamento é feito por um global scope no Eloquent: toda query de um modelo tenant é automaticamente filtrada por site_id a partir do tenant resolvido pelo Filament. O resultado é zero vazamento de dados entre sites, com a regra de isolamento explícita no código e coberta por testes, não escondida atrás de mágica de framework.
Num produto multi-tenant um bug que vaza dados de um cliente para outro não é um bug comum, é um incidente de segurança. Por isso o isolamento é testado, não confiado.
Modelagem de conteúdo dinâmica em PostgreSQL com JSONB
Esta é a decisão mais importante do projeto. Em vez de criar uma tabela e uma migration para cada novo tipo de conteúdo, o Rush armazena o schema das Collections e os dados das Entries em JSONB no PostgreSQL, com índices GIN para busca. Na prática: um usuário pode criar uma nova Collection, com seus próprios campos, sem que uma única migration rode no banco.
Isso é o que permite o sistema de Collections no estilo Notion/Statamic: listas e bancos de dados que o usuário monta sozinho, podendo inclusive encadeá-los como dependências hierárquicas. Marcas de carro que se desdobram em modelos. Estados que se desdobram em cidades, em cascata reativa. Ou algo simples como uma lista de "tipos de tecnologia" aplicada a uma collection para virar um campo de seleção na hora de criar uma entry. O modelo de dados deixa de ser definido por mim, no código, e passa a ser definido por quem usa, em runtime.
Geração de classes PHP em runtime para Custom Blocks
Este é o truque técnico de que mais me orgulho. Os Custom Blocks do editor de conteúdo são definidos pelo usuário no banco — nome, ícone, campos — e precisam virar classes PHP reais para o editor (Filament RichEditor/TipTap) reconhecê-los.
A primeira abordagem foi class_alias(), mas ela tem uma limitação: dentro do método, static::class continua retornando a classe base, então o bloco não sabe quem ele é. A solução foi gerar subclasses reais em runtime via eval(), onde cada bloco conhece o próprio slug.
Usar eval() é o tipo de decisão que exige justificar o trade-off de segurança, e eu justifico: o template do código é hardcoded, a única parte dinâmica é o slug (validado pelo banco e sanitizado via Str::studly()), e nenhum input de usuário chega ao eval(). É a solução certa para um problema real, com o risco mapeado e contido — não esperteza gratuita.
Performance de entrega: Octane + RoadRunner, respostas abaixo de 20ms
Um CMS headless vive ou morre pela latência da API, porque é ela que alimenta os frontends. Rodo o Rush sobre Laravel Octane com RoadRunner (v2025.1.6, 4 workers, 256MB cada), mantendo a aplicação viva em memória entre requisições em vez de subir e derrubar o framework a cada chamada. O resultado são respostas de API de ~20ms em endpoints simples e ~50ms nos complexos, rápidas o suficiente para servir sites estáticos via SSG com webhooks de rebuild, com cache de API no Redis por cima.
Operar Octane impõe disciplina: estado compartilhado entre requisições é uma armadilha. O código foi escrito com isso em mente — sem propriedades estáticas acumulando dados de request, injeção de dependência em vez de singletons com estado, e workers que reciclam a cada 10.000 jobs para conter vazamentos de memória.
i18n como fundação, não como remendo
O Rush é i18n-first: foi pensado em multi-idioma desde a base, com Spatie Translatable. É possível criar entries e outros conteúdos em múltiplos idiomas nativamente, e a própria plataforma está disponível em português e inglês. Internacionalização adicionada depois é sempre uma cicatriz; aqui ela é estrutura.
A escolha do PostgreSQL: uma decisão com dados
O Rush começou em MySQL e migrou para PostgreSQL — e essa migração foi uma decisão arquitetural, não cosmética. Como o sistema inteiro depende de JSONB para o modelo de conteúdo dinâmico, medi o ganho: queries em JSON ficaram de 3 a 5 vezes mais rápidas com índices GIN, ganhei full-text search nativo com stemming em português, e melhor concorrência para os queue workers. Migrar foi nadar a favor da corrente do que o produto já era.
O que o Rush faz
Por baixo dessas decisões, o Rush é um CMS completo, não um protótipo:
- Collections personalizáveis com 13+ tipos de campo e um sistema de listas/bancos reutilizáveis e encadeáveis como dependências
- Custom Blocks gerados em runtime, com editor de conteúdo estilo Notion (TipTap) e blocos prontos como YouTube e galeria com lightbox
- Block builder de homepage para montar a página inicial visualmente
- Form builder com captura automática de UTMs/referrer e disparo de e-mails para empresa e remetente
- Menu builder hierárquico, tags, categorias e webhooks
- Sistema de membros para sites com conteúdo exclusivo por área logada
- Gestão de usuários e papéis com 104+ permission nodes, no padrão
ação:recursodo Filament - Integração com Google Analytics via OAuth2 e analytics próprio de pageviews
- Importador de WordPress que converte HTML em blocos, com preview e dry-run
- Integração MCP: controlar o CMS via LLM (ChatGPT, Claude) por linguagem natural, com tokens isolados por tenant
- Conversão automática de imagens para WebP em todos os campos de imagem, com 50-70% de economia de espaço
- Plataforma bilíngue (PT-BR/EN) de ponta a ponta
A engenharia por trás
O que torna o Rush sustentável a longo prazo não é a lista de features, é o rigor por baixo delas:
- 603 testes automatizados com Pest, porque num produto multi-tenant testar o isolamento não é opcional.
- PHPStan/Larastan Level 5 para análise estática e detecção de erros antes do runtime, com Laravel Pint garantindo o padrão de código.
- CI/CD via GitHub Actions rodando testes, análise estática, code style, auditoria de segurança e build do frontend a cada push, com deploy em ~25 segundos.
- Eliminação sistemática de N+1, eager loading e cache em Redis — o tipo de trabalho invisível que mantém um sistema rápido conforme cresce.
- Documentação como código, no estilo ADR (Architecture Decision Records). Cada decisão de peso está registrada, porque um produto de um desenvolvedor só sobrevive à passagem do tempo se as decisões não vivem só na cabeça de quem as tomou.
A infraestrutura
O Rush roda em servidores Hetzner gerenciados via Coolify, com PostgreSQL 16, Redis 7, Nginx e Supervisor para os queue workers. É uma escolha de self-hosting que mantém o custo previsível — a operação inteira fica na casa de poucas dezenas de reais por mês — e o controle nas minhas mãos, sem depender de plataformas gerenciadas caras. Erro do Sentry, backup automatizado para S3 com lifecycle policy, e monitoramento completam o quadro. O mesmo princípio que guia o código guia a infra: a solução mais simples e direta que entrega o resultado, sem complexidade comprada por status.
O que esse projeto demonstra
O Rush CMS é a prova de conceito ambulante da minha forma de trabalhar. Ele mostra três coisas que um case de cliente raramente consegue mostrar com a mesma clareza:
Profundidade arquitetural. As decisões difíceis — isolamento de tenant por global scope, modelagem dinâmica em JSONB, geração de classes em runtime, performance via Octane, a migração medida para PostgreSQL — foram todas tomadas e defendidas por mim, e estão em produção sustentando dados reais de clientes reais.
Manutenção de longo prazo. Construir um MVP é fácil; manter um produto multi-tenant vivo, testado e rápido ao longo de meses, com CI/CD e documentação de decisões, é o que separa quem prototipa de quem sustenta sistema em produção.
Pragmatismo sob restrição. Um único desenvolvedor, infraestrutura barata, stack enxuta, e ainda assim um CMS arquitetado para 50+ sites isolados, servindo abaixo de 20ms. Não é sobre ter recursos infinitos; é sobre tomar a decisão certa em cada bifurcação.
Se o NR Secure mostra que eu resolvo a dor de um cliente, o Rush CMS mostra que eu construo e sustento o produto inteiro.