Pular para o conteúdo

Backstage

Plataforma de portal interno para desenvolvedores de código aberto do Spotify para gerenciar catálogo de software e experiência do desenvolvedor.

ComandoDescrição
npx @backstage/create-app@latestCriar nova aplicação Backstage
npx @backstage/create-app@latest --skip-installCriar app sem instalar dependências
cd my-backstage-app && yarn installInstalar dependências
yarn devIniciar frontend e backend em modo de desenvolvimento
yarn startIniciar apenas o frontend
yarn start-backendIniciar apenas o backend
yarn build:backendCompilar backend para produção
yarn buildCompilar todos os pacotes
node_modules/.bin/backstage-cli --versionMostrar versão do CLI Backstage
ComandoDescrição
yarn build:backend --config ../../app-config.yamlCompilar backend com config
docker build -t backstage -f packages/backend/Dockerfile .Construir imagem Docker
docker run -p 7007:7007 backstageExecutar contêiner Backstage
ComandoDescrição
yarn backstage-cli package startIniciar um pacote em modo dev
yarn backstage-cli package buildCompilar um pacote
yarn backstage-cli package lintLint do código-fonte do pacote
yarn backstage-cli package testExecutar testes do pacote
yarn backstage-cli repo build --allCompilar todos os pacotes no monorepo
yarn backstage-cli repo lint --allLint de todos os pacotes
yarn backstage-cli versions:bumpAtualizar dependências Backstage para a última versão
yarn backstage-cli versions:bump --release nextAtualizar para próximo pre-release
yarn backstage-cli migrate package-rolesMigrar pacotes para usar roles
ComandoDescrição
yarn backstage-cli create-pluginCriar novo plugin de frontend
yarn backstage-cli create-plugin --backendCriar novo plugin de backend
yarn backstage-cli create-plugin --id my-pluginCriar plugin com ID específico
yarn newCriar componente interativamente a partir de template
ComandoDescrição
Adicionar catalog-info.yaml na raiz do repoRegistrar componente no catálogo
kind: Component no catalog-info.yamlDefinir um componente de software
kind: API no catalog-info.yamlDefinir uma entidade de API
kind: System no catalog-info.yamlDefinir um agrupamento de sistema
kind: Domain no catalog-info.yamlDefinir um domínio de negócio
kind: Resource no catalog-info.yamlDefinir recurso de infraestrutura
kind: Group no catalog-info.yamlDefinir uma equipe/grupo
kind: User no catalog-info.yamlDefinir um usuário
kind: Location no catalog-info.yamlReferenciar outros arquivos de catálogo
ComandoDescrição
Definir spec.owner: team-nameDefinir proprietário da entidade
Definir spec.lifecycle: productionDefinir estágio do ciclo de vida da entidade
Definir spec.type: serviceDefinir tipo do componente (service, website, library)
Definir spec.dependsOn: ['component:other']Definir dependências
Definir spec.providesApis: ['api-name']Declarar APIs fornecidas
Definir spec.consumesApis: ['api-name']Declarar APIs consumidas
Definir spec.system: system-nameAtribuir a um sistema
Definir metadata.annotations para integraçõesConectar a CI/CD, monitoramento, etc.
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: payment-service
  description: Gerencia processamento de pagamentos e faturamento
  annotations:
    github.com/project-slug: org/payment-service
    backstage.io/techdocs-ref: dir:.
    jenkins.io/job-full-name: payment-service/main
    pagerduty.com/service-id: PABC123
    sonarqube.org/project-key: org_payment-service
  tags:
    - java
    - payments
  links:
    - url: https://dashboard.example.com/payments
      title: Dashboard de Monitoramento
      icon: dashboard
    - url: https://wiki.example.com/payment-service
      title: Wiki
spec:
  type: service
  lifecycle: production
  owner: team-payments
  system: billing
  providesApis:
    - payment-api
  consumesApis:
    - user-api
    - notification-api
  dependsOn:
    - resource:payments-db
    - component:auth-service
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
  name: payment-api
  description: API REST de processamento de pagamentos
  tags:
    - rest
    - payments
spec:
  type: openapi
  lifecycle: production
  owner: team-payments
  system: billing
  definition: |
    openapi: "3.0.0"
    info:
      title: Payment API
      version: 1.0.0
    paths:
      /payments:
        post:
          summary: Criar um pagamento
          responses:
            "201":
              description: Pagamento criado
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
  name: billing
  description: Sistema de faturamento e processamento de pagamentos
spec:
  owner: team-payments
  domain: commerce
---
apiVersion: backstage.io/v1alpha1
kind: Domain
metadata:
  name: commerce
  description: Domínio de e-commerce cobrindo pedidos, pagamentos e fulfillment
spec:
  owner: group:engineering-leadership
ComandoDescrição
kind: Template no template.yamlDefinir um template de software
Definir spec.type: serviceTemplate cria um serviço
Definir spec.steps[] para ações do templateDefinir etapas de scaffolding
action: fetch:templateBuscar e renderizar arquivos do template
action: publish:githubPublicar repo scaffolded no GitHub
action: publish:github:pull-requestCriar PR em vez de novo repo
action: catalog:registerRegistrar entidade criada no catálogo
action: github:actions:dispatchDisparar workflow do GitHub Actions
Usar ${{ parameters.name }} nos templatesReferenciar parâmetros de entrada do usuário
Definir spec.parameters[] para campos de formulárioDefinir formulário de entrada do template
Usar ui:widget: textarea nos parâmetrosPersonalizar widget do campo de formulário
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: microservice-template
  title: Criar um Microsserviço
  description: Scaffoldar novo microsserviço com CI/CD, monitoramento e documentação
  tags:
    - recommended
    - microservice
spec:
  owner: team-platform
  type: service
  parameters:
    - title: Detalhes do Serviço
      required:
        - name
        - description
        - owner
      properties:
        name:
          title: Nome do Serviço
          type: string
          description: Nome único do serviço
          ui:autofocus: true
          ui:options:
            rows: 5
        description:
          title: Descrição
          type: string
        owner:
          title: Proprietário
          type: string
          description: Equipe proprietária deste serviço
          ui:field: OwnerPicker
          ui:options:
            catalogFilter:
              kind: Group
    - title: Infraestrutura
      properties:
        language:
          title: Linguagem
          type: string
          enum: ["go", "java", "python", "typescript"]
          default: go
        database:
          title: Banco de Dados
          type: string
          enum: ["postgres", "mysql", "none"]
          default: postgres
        enableMonitoring:
          title: Ativar Monitoramento
          type: boolean
          default: true
  steps:
    - id: fetch-base
      name: Buscar Template Base
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          description: ${{ parameters.description }}
          owner: ${{ parameters.owner }}
          language: ${{ parameters.language }}
    - id: publish
      name: Publicar no GitHub
      action: publish:github
      input:
        allowedHosts: ["github.com"]
        repoUrl: github.com?owner=my-org&repo=${{ parameters.name }}
        description: ${{ parameters.description }}
        defaultBranch: main
        repoVisibility: internal
    - 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 }}
ComandoDescrição
yarn add @backstage/plugin-catalogInstalar plugin de catálogo
yarn add @backstage/plugin-techdocsInstalar plugin TechDocs
yarn add @backstage/plugin-kubernetesInstalar plugin Kubernetes
yarn add @backstage/plugin-github-actionsInstalar plugin GitHub Actions
yarn add @backstage/plugin-searchInstalar plugin de busca
yarn add @backstage/plugin-scaffolderInstalar plugin scaffolder
yarn add @backstage/plugin-api-docsInstalar plugin de docs de API
yarn add @backstage/plugin-cost-insightsInstalar plugin de insights de custos

Registrar plugins de frontend em packages/app/src/App.tsx:

import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
import { TechDocsReaderPage } from '@backstage/plugin-techdocs';
import { SearchPage } from '@backstage/plugin-search';

const routes = (
  <FlatRoutes>
    <Route path="/catalog" element={<CatalogIndexPage />} />
    <Route path="/catalog/:namespace/:kind/:name" element={<CatalogEntityPage />}>
      <EntityLayout>
        <EntityLayout.Route path="/" title="Overview">
          <EntityOverviewContent />
        </EntityLayout.Route>
        <EntityLayout.Route path="/api" title="API">
          <EntityApiContent />
        </EntityLayout.Route>
        <EntityLayout.Route path="/docs" title="Docs">
          <EntityTechDocsContent />
        </EntityLayout.Route>
      </EntityLayout>
    </Route>
    <Route path="/docs" element={<TechDocsReaderPage />} />
    <Route path="/search" element={<SearchPage />} />
    <Route path="/catalog-graph" element={<CatalogGraphPage />} />
  </FlatRoutes>
);

Registrar plugins de backend em packages/backend/src/index.ts:

import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

backend.add(import('@backstage/plugin-app-backend'));
backend.add(import('@backstage/plugin-catalog-backend'));
backend.add(import('@backstage/plugin-catalog-backend-module-github-org'));
backend.add(import('@backstage/plugin-scaffolder-backend'));
backend.add(import('@backstage/plugin-techdocs-backend'));
backend.add(import('@backstage/plugin-search-backend'));
backend.add(import('@backstage/plugin-search-backend-module-catalog'));
backend.add(import('@backstage/plugin-search-backend-module-techdocs'));
backend.add(import('@backstage/plugin-auth-backend'));
backend.add(import('@backstage/plugin-auth-backend-module-github-provider'));
backend.add(import('@backstage/plugin-kubernetes-backend'));

backend.start();
ComandoDescrição
npx @techdocs/cli servePré-visualizar TechDocs localmente
npx @techdocs/cli serve --docker-image techdocs-containerServir usando imagem Docker personalizada
npx @techdocs/cli generateGerar site estático TechDocs
npx @techdocs/cli generate --source-dir .Gerar de diretório específico
npx @techdocs/cli publish --publisher-type googleGcsPublicar TechDocs no GCS
npx @techdocs/cli publish --publisher-type awsS3Publicar TechDocs no S3
Adicionar anotação backstage.io/techdocs-refHabilitar TechDocs para entidade
Criar diretório docs/ com mkdocs.ymlConfigurar fonte de TechDocs
Definir techdocs.builder: 'local' na configUsar builder TechDocs local
Definir techdocs.builder: 'external' na configUsar builder CI/CD externo
site_name: Payment Service
nav:
  - Home: index.md
  - Architecture: architecture.md
  - API Reference: api-reference.md
  - Runbooks:
      - Deployment: runbooks/deployment.md
      - Incident Response: runbooks/incident-response.md
plugins:
  - techdocs-core
markdown_extensions:
  - admonition
  - pymdownx.highlight
  - pymdownx.superfences
ComandoDescrição
yarn add @backstage/plugin-searchInstalar frontend de busca
yarn add @backstage/plugin-search-backendInstalar backend de busca
yarn add @backstage/plugin-search-backend-module-catalogAdicionar collator de busca do catálogo
yarn add @backstage/plugin-search-backend-module-techdocsAdicionar collator de busca TechDocs
Configurar motor de busca no app-config.yamlConfigurar Lunr, Elasticsearch ou PgStore
Definir search.pg na configUsar PostgreSQL para busca
Definir search.elasticsearch na configUsar Elasticsearch para busca
ComandoDescrição
Editar app-config.yamlArquivo de configuração principal
Editar app-config.local.yamlSobrescritas de desenvolvimento local
Editar app-config.production.yamlConfiguração de produção
Definir app.baseUrl na configConfigurar URL do frontend
Definir backend.baseUrl na configConfigurar URL do backend
Definir backend.database na configConfigurar conexão com banco de dados
Definir backend.cors.origin na configConfigurar origens CORS
Definir auth.providers na configConfigurar provedores de autenticação
Definir catalog.locations[] na configAdicionar fontes de entidades do catálogo
Definir catalog.rules[] na configDefinir regras de validação de entidades
Definir integrations.github[] na configConfigurar token de integração GitHub
app:
  title: Portal do Desenvolvedor da Minha Empresa
  baseUrl: http://localhost:3000

organization:
  name: Minha Empresa

backend:
  baseUrl: http://localhost:7007
  listen:
    port: 7007
  cors:
    origin: http://localhost:3000
    methods: [GET, HEAD, PATCH, POST, PUT, DELETE]
  database:
    client: pg
    connection:
      host: ${POSTGRES_HOST}
      port: ${POSTGRES_PORT}
      user: ${POSTGRES_USER}
      password: ${POSTGRES_PASSWORD}

integrations:
  github:
    - host: github.com
      token: ${GITHUB_TOKEN}

auth:
  environment: development
  providers:
    github:
      development:
        clientId: ${GITHUB_CLIENT_ID}
        clientSecret: ${GITHUB_CLIENT_SECRET}

catalog:
  import:
    entityFilename: catalog-info.yaml
    pullRequestBranchName: backstage-integration
  rules:
    - allow: [Component, System, API, Resource, Location, Domain, Group, User]
  locations:
    - type: url
      target: https://github.com/my-org/backstage-catalog/blob/main/all-components.yaml
    - type: github-discovery
      target: https://github.com/my-org
    - type: github-org
      target: https://github.com/my-org

techdocs:
  builder: local
  generator:
    runIn: local
  publisher:
    type: local

kubernetes:
  serviceLocatorMethod:
    type: multiTenant
  clusterLocatorMethods:
    - type: config
      clusters:
        - url: ${K8S_CLUSTER_URL}
          name: production
          authProvider: serviceAccount
          serviceAccountToken: ${K8S_TOKEN}
RelacionamentoDeParaDescrição
ownerOfGroup/UserComponent/APIGrupo é proprietário da entidade
ownedByComponent/APIGroup/UserEntidade é de propriedade do grupo
consumesApiComponentAPIComponente usa uma API
providesApiComponentAPIComponente expõe uma API
dependsOnComponentComponent/ResourceComponente depende de outro
dependencyOfComponent/ResourceComponentÉ uma dependência de
partOfComponentSystemComponente pertence ao sistema
hasPartSystemComponentSistema contém componente
parentOfGroupGroupRelacionamento de equipe pai
childOfGroupGroupRelacionamento de equipe filho
memberOfUserGroupUsuário pertence ao grupo
hasMemberGroupUserGrupo contém usuário
  1. Usar catalog-info.yaml em todo repositório — garanta que todos os serviços, bibliotecas e APIs estejam registrados no catálogo para visibilidade completa.

  2. Definir propriedade significativa — toda entidade deve ter um campo owner apontando para um Group válido, permitindo responsabilidade e roteamento.

  3. Anotar entidades de forma rica — adicione anotações para CI/CD, monitoramento, PagerDuty e documentação para tornar o catálogo um verdadeiro hub.

  4. Criar templates para caminhos dourados — use o scaffolder para definir formas padronizadas de criar novos serviços, garantindo consistência.

  5. Implementar TechDocs — mantenha documentação junto ao código usando o plugin TechDocs e mkdocs.yml para documentação viva.

  6. Usar descoberta GitHub — configure github-discovery nas localizações do catálogo para descobrir e registrar repositórios automaticamente.

  7. Modelar sua organização — defina Groups e Users para refletir a estrutura da sua equipe, habilitando rastreamento de propriedade e páginas de equipe.

  8. Manter app-config.yaml consciente do ambiente — use app-config.local.yaml para desenvolvimento e variáveis de ambiente para secrets de produção.

  9. Construir um ecossistema de plugins — crie plugins personalizados de frontend e backend para estender o Backstage com ferramentas específicas da sua organização.

  10. Definir Systems e Domains — modele a arquitetura de alto nível usando Systems e Domains para dar aos desenvolvedores um mapa da sua plataforma.