DEV Community

Cover image for Backstage o portal de desenvolvedores da CNCF, como funciona por dentro
Kauê Matos
Kauê Matos

Posted on

Backstage o portal de desenvolvedores da CNCF, como funciona por dentro

O Backstage é um framework open source para construir portais de desenvolvedores: uma interface única onde times encontram seus serviços, criam novos projetos a partir de modelos padronizados, leem a documentação e acessam as ferramentas de infraestrutura que usam no dia a dia. Ele não é um produto pronto para instalar e usar; é uma base que você monta, estende com plugins e hospeda por conta própria.

O projeto nasceu dentro do Spotify, para domar a quantidade crescente de serviços e ferramentas internas. Foi aberto ao público em março de 2020, doado à CNCF (Cloud Native Computing Foundation) como projeto Sandbox em setembro de 2020 e promovido ao nível Incubating em março de 2022. Hoje é uma das bases mais usadas para o que o mercado chama de Internal Developer Portal (IDP).

Tecnicamente, o Backstage é uma aplicação TypeScript: um frontend em React e um backend em Node.js, ligados por um sistema de plugins. Este artigo percorre o problema que ele resolve, sua arquitetura, os três pilares (Catalog, Templates e TechDocs), o modelo de plugins, autenticação, deploy e o que esperar da adoção.

O problema que o Backstage resolve

O Backstage ataca a carga cognitiva de quem desenvolve software em uma organização com muitos times, serviços e ferramentas. Em empresas que adotam microsserviços e nuvem, as mesmas perguntas se repetem o tempo todo, e a resposta fica espalhada em wikis, planilhas, chats e na cabeça de poucas pessoas.

  • Quem é dono deste serviço? E onde está o repositório, o pipeline, o dashboard e o canal de plantão?
  • Como crio um novo serviço seguindo o padrão da empresa? Cada time acaba montando o seu, com variações de pipeline, segurança e observabilidade.
  • Onde está a documentação, e ela está atualizada? Wikis desconectadas do código envelhecem rápido.
  • Quais serviços dependem de qual API? Sem esse mapa, avaliar o impacto de uma mudança vira investigação manual.

A resposta do Backstage é centralizar esses metadados em um catálogo vivo, alimentado pelos próprios repositórios, e expor sobre ele ações e visões: criar, documentar, observar e operar.

Onde entra o platform engineering

O Backstage é a camada de interface de uma plataforma interna de desenvolvedores. Um time de plataforma oferece capacidades prontas (pipelines, ambientes, templates, observabilidade) e o portal é a vitrine de autoatendimento delas. A ideia central são os golden paths: caminhos recomendados e já configurados que tornam o jeito certo de fazer também o jeito mais fácil. Quem quiser sair do caminho pode, mas quem seguir ganha velocidade e segurança por padrão.

Arquitetura

O Backstage tem uma arquitetura em camadas: um frontend React que roda no navegador, um backend Node.js que concentra a lógica, as credenciais e o acesso a dados, e as fontes externas que o backend consulta em nome do usuário.

[embedded content: arquitetura do Backstage · 3 camadas]

O navegador conversa apenas com o backend, e é o backend que acessa o PostgreSQL, o armazenamento do TechDocs e os sistemas externos, o que mantém tokens e segredos fora do alcance do usuário.

As peças

  • Frontend: uma aplicação de página única em React. Cada plugin registra suas páginas e seus componentes, e o app os compõe em rotas, abas de entidade e cartões.
  • Backend: um processo Node.js (TypeScript) que hospeda os plugins de servidor. Cada plugin é isolado: tem seus endpoints, seu esquema de banco e seus serviços injetados (logger, banco, configuração, autenticação).
  • Banco de dados: guarda o estado do catálogo, o histórico das tarefas do Scaffolder e dados de outros plugins. PostgreSQL em produção.
  • Armazenamento de objetos: opcional, usado pelo TechDocs para servir a documentação já gerada.
  • Sistemas externos: repositórios Git, clusters Kubernetes, ferramentas de CI/CD, provedores de identidade e nuvens, acessados por plugins e integrações configuradas no app-config.yaml.

Os dois processos costumam ser publicados juntos: o backend serve também os arquivos estáticos do frontend, e todo o conjunto vira uma única imagem de contêiner. Em instalações maiores, é possível separar frontend e backend ou dividir o backend em vários serviços por plugin.

Software Catalog

O Software Catalog é o coração do Backstage: um inventário central de tudo o que a organização constrói e opera, com donos, relações e links para as ferramentas de cada item. Os outros pilares dependem dele para saber de qual serviço se está falando.

O modelo de entidades

Cada item do catálogo é uma entidade, descrita por um arquivo YAML com apiVersion, kind, metadata e spec. Os tipos (kind) padrão são:

Kind Representa Exemplo
Component Uma unidade de software Serviço, website, biblioteca
API Uma interface exposta por um componente OpenAPI, gRPC, GraphQL, AsyncAPI
Resource Infraestrutura da qual componentes dependem Banco, fila, bucket S3
System Conjunto de componentes, APIs e recursos que formam um produto Sistema de pagamentos
Domain Agrupamento de sistemas de uma área de negócio Financeiro
Group Time ou unidade organizacional Time de plataforma
User Pessoa Desenvolvedor
Location Ponteiro para outros arquivos de descritor Repositório com vários YAMLs

As entidades se ligam por relações como ownedBy, dependsOn, providesApi, consumesApi e partOf. É isso que permite responder, por exemplo, quais componentes consomem uma API que será descontinuada.

O descritor catalog-info.yaml

Por convenção, cada repositório guarda na raiz um catalog-info.yaml que descreve seu componente. O metadado vive junto do código, versionado e revisado como qualquer outra mudança.

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: servico-pagamentos
  description: API de processamento de pagamentos
  annotations:
    github.com/project-slug: minha-org/servico-pagamentos
    backstage.io/techdocs-ref: dir:.
  tags:
    - java
    - spring-boot
spec:
  type: service
  lifecycle: production
  owner: group:time-pagamentos
  system: plataforma-financeira
  providesApis:
    - api-pagamentos
  dependsOn:
    - resource:default/postgres-pagamentos
Enter fullscreen mode Exit fullscreen mode

As annotations são o mecanismo de ligação com plugins: a de github.com/project-slug faz o plugin do GitHub saber qual repositório mostrar na página da entidade, e a de backstage.io/techdocs-ref indica onde está a documentação.

Como o catálogo é alimentado

O backend do catálogo roda um processo contínuo de ingestão em três etapas:

  1. Entity providers descobrem descritores. Há providers para GitHub, GitLab, Bitbucket, Azure DevOps, AWS S3 e outros, e eles podem varrer uma organização inteira procurando catalog-info.yaml. Também é possível registrar uma URL manualmente na interface.
  2. Processors validam cada entidade, resolvem referências, emitem relações e podem enriquecê-la com dados externos.
  3. Stitching consolida o resultado final de cada entidade e o grava no banco, de onde o frontend lê.

O catálogo atualiza em ciclos periódicos, então uma mudança no YAML aparece no portal após alguns minutos, sem ação manual. Dados de organização (grupos e usuários) costumam vir de um provedor de identidade, como Microsoft Entra ID, Okta, LDAP ou GitHub, para manter os donos sincronizados com a realidade.

Software Templates

Os Software Templates (o plugin Scaffolder) transformam um formulário em um repositório novo, já configurado, e registrado no catálogo. O desenvolvedor escolhe um modelo, preenche alguns campos e, minutos depois, tem código, pipeline, documentação e dono definidos, sem abrir chamado para o time de plataforma.

Como um template é definido

Um template é uma entidade do catálogo com kind: Template. Ele declara os parâmetros (que viram um formulário gerado a partir de JSON Schema) e os passos (ações executadas em sequência).

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: servico-spring-boot
  title: Novo serviço Spring Boot
  description: Cria um serviço Java com pipeline e docs prontos
spec:
  owner: group:time-plataforma
  type: service

  parameters:
    - title: Informações do serviço
      required: [nome, dono]
      properties:
        nome:
          type: string
          description: Nome do serviço
        dono:
          type: string
          title: Time responsável
          ui:field: OwnerPicker
          ui:options:
            allowedKinds: [Group]
    - title: Destino
      required: [repoUrl]
      properties:
        repoUrl:
          type: string
          ui:field: RepoUrlPicker
          ui:options:
            allowedHosts: [github.com]

  steps:
    - id: fetch
      name: Gerar código a partir do esqueleto
      action: fetch:template
      input:
        url: ./skeleton
        values:
          nome: ${{ parameters.nome }}
          dono: ${{ parameters.dono }}

    - id: publish
      name: Criar repositório
      action: publish:github
      input:
        repoUrl: ${{ parameters.repoUrl }}
        description: ${{ parameters.nome }}

    - id: register
      name: Registrar no catálogo
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml

  output:
    links:
      - title: Repositório
        url: ${{ steps['publish'].output.remoteUrl }}
      - title: Abrir no catálogo
        icon: catalog
        entityRef: ${{ steps['register'].output.entityRef }}
Enter fullscreen mode Exit fullscreen mode

Peças do mecanismo

  • Esqueleto (skeleton): uma pasta de arquivos com marcadores ${{ values.nome }}, renderizada pela ação fetch:template (engine Nunjucks). É nele que ficam o Dockerfile, o workflow de CI, o catalog-info.yaml e a estrutura de documentação.
  • Ações: funções que o backend executa, como fetch:template, publish:github, publish:gitlab e catalog:register. É possível escrever ações customizadas, por exemplo para criar um recurso em nuvem ou abrir um ticket.
  • Campos de formulário: componentes como OwnerPicker e RepoUrlPicker dão uma experiência guiada, e há suporte a campos customizados.
  • Execução e log: cada execução vira uma tarefa com log em tempo real na interface, o que facilita diagnosticar falhas.

O valor para a organização está no que o esqueleto embute: padrões de segurança, observabilidade, estrutura de pipeline e metadados de catálogo nascem corretos em todo serviço novo. Atualizar o template melhora os próximos projetos, mas não altera os já criados, ponto que costuma exigir uma estratégia à parte de manutenção.

TechDocs

O TechDocs aplica a ideia de docs-like-code: a documentação técnica fica em Markdown dentro do mesmo repositório do código e aparece no portal, na página do componente. Quem muda o código muda a documentação no mesmo pull request, o que reduz o envelhecimento.

Como funciona

O TechDocs usa o MkDocs como gerador de site estático, com o plugin techdocs-core. A configuração fica em um mkdocs.yml na raiz do repositório, e a entidade aponta para ele pela annotation backstage.io/techdocs-ref.

# mkdocs.yml
site_name: servico-pagamentos
nav:
  - Início: index.md
  - Arquitetura: arquitetura.md
  - Runbooks: runbooks.md
plugins:
  - techdocs-core
Enter fullscreen mode Exit fullscreen mode

Duas estratégias de build

Estratégia Quem gera o site Quando usar
Basic (techdocs.builder: local) O próprio backend do Backstage, sob demanda Testes e instalações pequenas
Recommended (techdocs.builder: external) Um pipeline de CI, a cada mudança, publicando em um armazenamento Produção

Na estratégia recomendada, o CI roda a CLI techdocs-cli generate e techdocs-cli publish, enviando o site gerado para um armazenamento de objetos (AWS S3, Google Cloud Storage, Azure Blob Storage ou OpenStack Swift). O Backstage apenas lê dali. Isso tira a carga de build do backend e permite escalar a leitura de forma independente.

Benefícios e cuidados

O resultado é uma documentação com busca integrada ao portal, navegação lateral e a mesma autenticação do restante da plataforma. O cuidado é cultural: o plugin entrega a infraestrutura, mas a qualidade do conteúdo continua dependendo de cada time. Um bom começo é incluir no template um docs/ mínimo, com seções para visão geral, arquitetura e runbook de operação.

Plugins e ecossistema

Tudo no Backstage é plugin, inclusive o Catalog, o Scaffolder e o TechDocs. Essa é a decisão de design que o torna extensível: o portal é uma casca que carrega plugins, e cada plugin traz sua interface, sua lógica de servidor ou os dois.

Como um plugin é composto

Um plugin típico tem duas metades. O plugin de frontend é um pacote React que registra páginas, abas e cartões na interface. O plugin de backend é um serviço Node.js que expõe endpoints, acessa o banco, chama APIs externas e guarda credenciais, para que o navegador nunca as veja. Um plugin de frontend costuma consultar o seu backend, e esse backend consulta a ferramenta externa, por exemplo o GitHub, o Kubernetes ou o PagerDuty.

O backend atual é montado com o novo sistema de backend, em que o plugin é registrado com backend.add(...) e dependências como logger, banco, cache e configuração são injetadas como serviços. O Backstage também evolui um novo sistema de frontend baseado em extensões, mas parte dos plugins da comunidade ainda usa o modelo anterior, então vale conferir a compatibilidade antes de adotar.

Plugins populares

Categoria Exemplos
Código e CI/CD GitHub Actions, GitLab, Jenkins, CircleCI, Argo CD
Infraestrutura Kubernetes, Terraform, AWS, Azure, Google Cloud
Observabilidade e incidentes Grafana, Datadog, Prometheus, PagerDuty, Sentry
Segurança SonarQube, Snyk, relatórios de vulnerabilidades
Qualidade e maturidade Tech Insights, scorecards
Custos Cost Insights
Busca Pesquisa unificada sobre catálogo e docs (Lunr, PostgreSQL ou Elasticsearch)

O diretório de plugins no site do projeto lista centenas de opções, mantidas pelo Spotify, por fornecedores e pela comunidade. A qualidade varia: antes de depender de um plugin, verifique a data do último commit, a compatibilidade com a versão do Backstage em uso e se ele já migrou para o novo sistema de backend.

Criando o seu

O CLI do Backstage gera o esqueleto de um plugin com yarn new. O caminho comum em empresas é escrever plugins internos para exibir dados proprietários, como o status de uma plataforma interna ou o painel de custos do time, e ligar a página à entidade do catálogo por uma annotation.

Autenticação e permissões

O Backstage separa duas perguntas: quem é você (autenticação) e o que você pode fazer (autorização). A primeira vem pronta com vários provedores; a segunda é um framework que você configura.

Autenticação

O plugin de autenticação oferece provedores como GitHub, GitLab, Google, Microsoft Entra ID, Okta, Auth0, AWS ALB, OneLogin, além de OIDC e SAML genéricos. Ao concluir o login, um sign-in resolver associa a identidade externa a uma entidade User do catálogo, e é essa ligação que dá ao usuário seus grupos e, portanto, seus donos e permissões. Um resolver mal escrito, que associe a pessoa errada, é uma das falhas de configuração mais sérias, e vale revisá-lo com cuidado.

Por padrão, um projeto novo permite acesso como convidado, útil só em desenvolvimento. Em produção, desative esse acesso e configure o provedor corporativo.

Autorização com o Permission Framework

Sem configuração extra, qualquer usuário autenticado pode fazer quase tudo. O framework de permissões muda isso: os plugins declaram permissões (ler uma entidade, executar um template, remover do catálogo), e uma política em código decide, para cada requisição, se o usuário recebe ALLOW, DENY ou uma decisão condicional.

Um exemplo comum é restringir quem pode apagar entidades ao time de plataforma, ou limitar que templates aparecem para cada time. As condicionais permitem regras como "o usuário só edita entidades de que é dono", avaliadas no banco com eficiência.

Segurança do portal como um todo

O Backstage guarda tokens de integração (GitHub, nuvem, Kubernetes) e enxerga metadados sensíveis de toda a empresa, o que o torna um alvo valioso. Mantenha o portal atrás do SSO corporativo, guarde credenciais em um gerenciador de segredos, use permissões mínimas nos tokens de integração e acompanhe as atualizações de segurança do projeto, que lança versões com frequência mensal.

Instalação e deploy

Uma instância do Backstage é um projeto seu, gerado por um CLI, e não um pacote que você instala. Você cria o app, o versiona em um repositório próprio e o atualiza para acompanhar as versões do projeto.

Criando e rodando localmente

O pré-requisito é uma versão LTS do Node.js e o Yarn. O comando abaixo gera a estrutura do monorepo.

npx @backstage/create-app@latest
cd meu-portal
yarn start
Enter fullscreen mode Exit fullscreen mode

O projeto gerado tem dois pacotes principais: packages/app (frontend) e packages/backend (backend). No modo de desenvolvimento, o frontend responde em localhost:3000 e o backend em localhost:7007. A configuração fica em app-config.yaml, com variantes como app-config.production.yaml e app-config.local.yaml sobrepondo valores por ambiente.

Banco de dados

O desenvolvimento usa SQLite em memória, e produção exige PostgreSQL. Cada plugin de backend usa seu próprio banco lógico, e o Backstage cria o que for preciso. Em nuvem, um banco gerenciado (como Amazon RDS ou Aurora PostgreSQL) resolve backup, alta disponibilidade e atualização.

# app-config.production.yaml
app:
  baseUrl: https://backstage.minha-empresa.com
backend:
  baseUrl: https://backstage.minha-empresa.com
  database:
    client: pg
    connection:
      host: ${POSTGRES_HOST}
      port: ${POSTGRES_PORT}
      user: ${POSTGRES_USER}
      password: ${POSTGRES_PASSWORD}
Enter fullscreen mode Exit fullscreen mode

Empacotando e publicando

O caminho usual é gerar uma imagem de contêiner. O projeto traz um Dockerfile de exemplo em packages/backend, e o build típico compila o TypeScript, empacota o backend e embute o frontend estático para ser servido por ele.

yarn install --immutable
yarn tsc
yarn build:backend
docker build . -f packages/backend/Dockerfile --tag meu-portal:1.0.0
Enter fullscreen mode Exit fullscreen mode

A imagem roda em qualquer orquestrador: Kubernetes (com Helm chart, que a comunidade mantém), Amazon ECS ou EKS, Cloud Run e similares. Em um deploy típico, um balanceador termina o TLS, o serviço roda em duas ou mais réplicas, o PostgreSQL é gerenciado, os segredos vêm de um gerenciador (e não do app-config.yaml) e os arquivos do TechDocs ficam em um bucket de objetos.

Atualizações

O Backstage publica uma versão a cada mês, e o comando yarn backstage-cli versions:bump atualiza todos os pacotes @backstage/* de uma vez. Atualizar com regularidade custa menos que acumular meses de mudanças, e o site do projeto traz um upgrade helper que mostra o diff entre duas versões do projeto gerado.

Adoção na prática

O maior risco do Backstage não é técnico: é tratá-lo como um projeto de instalação em vez de um produto interno. O código é aberto e gratuito, mas o custo real está em manter, evoluir e convencer pessoas a usá-lo.

O custo de ser dono do portal

Um portal útil costuma exigir uma equipe dedicada, com conhecimento de TypeScript, React e Node.js. Cabe a ela atualizar versões todo mês, manter plugins internos, resolver quebras de compatibilidade e atender os times usuários. Organizações pequenas, sem um time de plataforma, costumam subestimar esse esforço.

Armadilhas frequentes

  • Catálogo desatualizado. Um catálogo com donos errados e serviços mortos perde a confiança em semanas. Automatize a descoberta, valide os descritores no CI e exija um dono para cada entidade.
  • Começar largo demais. Instalar dezenas de plugins antes de resolver uma dor concreta gera um portal cheio e sem uso. Comece com o catálogo e um template para o caso mais frequente.
  • Ausência de incentivo. Se a documentação e os templates do portal não são o caminho mais fácil, as pessoas continuam usando wikis e planilhas. O portal precisa economizar tempo desde o primeiro uso.
  • Template sem manutenção. Serviços criados a partir de um template não recebem suas atualizações; planeje como propagar correções (por exemplo, com ferramentas de atualização automática de dependências e pipelines reutilizáveis).
  • Confundir portal com plataforma. O Backstage é a interface. As capacidades por trás dele, como pipelines, ambientes e observabilidade, ainda precisam existir.

Como medir o sucesso

Indicadores úteis incluem a porcentagem de serviços no catálogo com dono definido, o tempo para criar um serviço novo e colocá-lo em produção, o uso ativo semanal do portal e a satisfação dos desenvolvedores em pesquisas curtas. Esses números sustentam a continuidade do investimento.

Alternativas e opções gerenciadas

Quem quer o resultado sem montar o portal pode olhar soluções que oferecem o Backstage hospedado ou alternativas de mercado. As principais opções são:

Opção Perfil
Red Hat Developer Hub Distribuição corporativa baseada no Backstage, com suporte
Roadie Backstage gerenciado como serviço
Port, Cortex, OpsLevel Portais de mercado (não baseados em Backstage), com configuração mais guiada e menos código

A escolha entre montar ou comprar depende de equipe disponível, necessidade de customização e orçamento. Verifique recursos e preços atuais direto com cada fornecedor, pois mudam com frequência.

Conclusão

O Backstage entrega um portal de desenvolvedores montado sobre três ideias simples: um catálogo alimentado pelo código, templates que codificam os caminhos recomendados e documentação que mora junto do código. O resto é plugin. Sua força é a extensibilidade e o respaldo da CNCF; seu custo é a necessidade de tratá-lo como um produto interno, com equipe, roadmap e métricas.

Um caminho prático para começar:

  1. Gere um app com npx @backstage/create-app e rode localmente.
  2. Registre dois ou três serviços reais com catalog-info.yaml e conecte o provider do seu repositório de código.
  3. Crie um template para o tipo de serviço mais comum na empresa.
  4. Ative o TechDocs com build externo em um bucket de objetos.
  5. Troque o acesso de convidado pelo SSO corporativo e defina uma política de permissões básica.
  6. Meça o uso e expanda os plugins só onde houver dor concreta.

Referências

Comandos, nomes de pacotes e recursos mudam entre versões; confirme sempre na documentação oficial.

Top comments (0)