Ir al contenido

Backstage

Plataforma de portal interno para desarrolladores de código abierto por Spotify para gestionar catálogos de software y experiencia del desarrollador.

ComandoDescripción
npx @backstage/create-app@latestCrear nueva aplicación Backstage
npx @backstage/create-app@latest --skip-installCrear app sin instalar dependencias
cd my-backstage-app && yarn installInstalar dependencias
yarn devIniciar frontend y backend en modo desarrollo
yarn startIniciar solo el frontend
yarn start-backendIniciar solo el backend
yarn build:backendCompilar backend para producción
yarn buildCompilar todos los paquetes
node_modules/.bin/backstage-cli --versionMostrar versión del CLI de Backstage
ComandoDescripción
yarn build:backend --config ../../app-config.yamlCompilar backend con configuración
docker build -t backstage -f packages/backend/Dockerfile .Compilar imagen Docker
docker run -p 7007:7007 backstageEjecutar contenedor Backstage
ComandoDescripción
yarn backstage-cli package startIniciar un paquete en modo desarrollo
yarn backstage-cli package buildCompilar un paquete
yarn backstage-cli package lintEjecutar lint del código fuente del paquete
yarn backstage-cli package testEjecutar tests del paquete
yarn backstage-cli repo build --allCompilar todos los paquetes del monorepo
yarn backstage-cli repo lint --allEjecutar lint en todos los paquetes
yarn backstage-cli versions:bumpActualizar dependencias de Backstage a la última versión
yarn backstage-cli versions:bump --release nextActualizar a pre-release siguiente
yarn backstage-cli migrate package-rolesMigrar paquetes para usar roles
ComandoDescripción
yarn backstage-cli create-pluginCrear nuevo plugin de frontend
yarn backstage-cli create-plugin --backendCrear nuevo plugin de backend
yarn backstage-cli create-plugin --id my-pluginCrear plugin con ID específico
yarn newCrear componente interactivamente desde plantilla
ComandoDescripción
Agregar catalog-info.yaml a la raíz del repoRegistrar componente en el catálogo
kind: Component en catalog-info.yamlDefinir un componente de software
kind: API en catalog-info.yamlDefinir una entidad API
kind: System en catalog-info.yamlDefinir una agrupación de sistema
kind: Domain en catalog-info.yamlDefinir un dominio de negocio
kind: Resource en catalog-info.yamlDefinir recurso de infraestructura
kind: Group en catalog-info.yamlDefinir un equipo/grupo
kind: User en catalog-info.yamlDefinir un usuario
kind: Location en catalog-info.yamlReferenciar otros archivos del catálogo
ComandoDescripción
Establecer spec.owner: team-nameEstablecer propiedad de la entidad
Establecer spec.lifecycle: productionEstablecer etapa del ciclo de vida de la entidad
Establecer spec.type: serviceEstablecer tipo de componente (service, website, library)
Establecer spec.dependsOn: ['component:other']Definir dependencias
Establecer spec.providesApis: ['api-name']Declarar APIs proporcionadas
Establecer spec.consumesApis: ['api-name']Declarar APIs consumidas
Establecer spec.system: system-nameAsignar a un sistema
Establecer metadata.annotations para integracionesConectar con CI/CD, monitoreo, etc.
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: payment-service
  description: Handles payment processing and billing
  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: Monitoring Dashboard
      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: Payment processing REST API
  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: Create a payment
          responses:
            "201":
              description: Payment created
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
  name: billing
  description: Billing and payment processing system
spec:
  owner: team-payments
  domain: commerce
---
apiVersion: backstage.io/v1alpha1
kind: Domain
metadata:
  name: commerce
  description: E-commerce domain covering orders, payments, and fulfillment
spec:
  owner: group:engineering-leadership
ComandoDescripción
kind: Template en template.yamlDefinir una plantilla de software
Establecer spec.type: serviceLa plantilla crea un servicio
Establecer spec.steps[] para acciones de plantillaDefinir pasos de scaffolding
action: fetch:templateObtener y renderizar archivos de plantilla
action: publish:githubPublicar repo scaffoldeado en GitHub
action: publish:github:pull-requestCrear PR en lugar de nuevo repo
action: catalog:registerRegistrar entidad creada en el catálogo
action: github:actions:dispatchDisparar flujo de trabajo de GitHub Actions
Usar ${{ parameters.name }} en plantillasReferenciar parámetros de entrada del usuario
Establecer spec.parameters[] para campos de formularioDefinir formulario de entrada de la plantilla
Usar ui:widget: textarea en parametersPersonalizar widget del campo de formulario
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: microservice-template
  title: Create a Microservice
  description: Scaffold a new microservice with CI/CD, monitoring, and docs
  tags:
    - recommended
    - microservice
spec:
  owner: team-platform
  type: service
  parameters:
    - title: Service Details
      required:
        - name
        - description
        - owner
      properties:
        name:
          title: Service Name
          type: string
          description: Unique name of the service
          ui:autofocus: true
          ui:options:
            rows: 5
        description:
          title: Description
          type: string
        owner:
          title: Owner
          type: string
          description: Team that owns this service
          ui:field: OwnerPicker
          ui:options:
            catalogFilter:
              kind: Group
    - title: Infrastructure
      properties:
        language:
          title: Language
          type: string
          enum: ["go", "java", "python", "typescript"]
          default: go
        database:
          title: Database
          type: string
          enum: ["postgres", "mysql", "none"]
          default: postgres
        enableMonitoring:
          title: Enable Monitoring
          type: boolean
          default: true
  steps:
    - id: fetch-base
      name: Fetch Base Template
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          description: ${{ parameters.description }}
          owner: ${{ parameters.owner }}
          language: ${{ parameters.language }}
    - id: publish
      name: Publish to 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: Register in Catalog
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml
  output:
    links:
      - title: Repository
        url: ${{ steps['publish'].output.remoteUrl }}
      - title: Open in Catalog
        icon: catalog
        entityRef: ${{ steps['register'].output.entityRef }}
ComandoDescripción
yarn add @backstage/plugin-catalogInstalar plugin de catálogo
yarn add @backstage/plugin-techdocsInstalar plugin de TechDocs
yarn add @backstage/plugin-kubernetesInstalar plugin de Kubernetes
yarn add @backstage/plugin-github-actionsInstalar plugin de GitHub Actions
yarn add @backstage/plugin-searchInstalar plugin de búsqueda
yarn add @backstage/plugin-scaffolderInstalar plugin de scaffolder
yarn add @backstage/plugin-api-docsInstalar plugin de documentación de API
yarn add @backstage/plugin-cost-insightsInstalar plugin de análisis de costos

Registrar plugins de frontend en 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 en 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();
ComandoDescripción
npx @techdocs/cli servePrevisualizar TechDocs localmente
npx @techdocs/cli serve --docker-image techdocs-containerServir usando imagen Docker personalizada
npx @techdocs/cli generateGenerar sitio estático de TechDocs
npx @techdocs/cli generate --source-dir .Generar desde directorio específico
npx @techdocs/cli publish --publisher-type googleGcsPublicar TechDocs en GCS
npx @techdocs/cli publish --publisher-type awsS3Publicar TechDocs en S3
Agregar anotación backstage.io/techdocs-refHabilitar TechDocs para entidad
Crear directorio docs/ con mkdocs.ymlConfigurar fuente de TechDocs
Establecer techdocs.builder: 'local' en configUsar constructor local de TechDocs
Establecer techdocs.builder: 'external' en configUsar constructor externo de CI/CD
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
ComandoDescripción
yarn add @backstage/plugin-searchInstalar frontend de búsqueda
yarn add @backstage/plugin-search-backendInstalar backend de búsqueda
yarn add @backstage/plugin-search-backend-module-catalogAgregar collator de búsqueda del catálogo
yarn add @backstage/plugin-search-backend-module-techdocsAgregar collator de búsqueda de TechDocs
Configurar motor de búsqueda en app-config.yamlConfigurar Lunr, Elasticsearch o PgStore
Establecer search.pg en configUsar PostgreSQL para búsqueda
Establecer search.elasticsearch en configUsar Elasticsearch para búsqueda
ComandoDescripción
Editar app-config.yamlArchivo de configuración principal
Editar app-config.local.yamlSobrecargas de desarrollo local
Editar app-config.production.yamlConfiguración de producción
Establecer app.baseUrl en configConfigurar URL del frontend
Establecer backend.baseUrl en configConfigurar URL del backend
Establecer backend.database en configConfigurar conexión de base de datos
Establecer backend.cors.origin en configConfigurar orígenes CORS
Establecer auth.providers en configConfigurar proveedores de autenticación
Establecer catalog.locations[] en configAgregar fuentes de entidades del catálogo
Establecer catalog.rules[] en configDefinir reglas de validación de entidades
Establecer integrations.github[] en configConfigurar token de integración con GitHub
app:
  title: My Company Developer Portal
  baseUrl: http://localhost:3000

organization:
  name: My Company

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}
RelaciónDesdeHaciaDescripción
ownerOfGroup/UserComponent/APIEl grupo es propietario de la entidad
ownedByComponent/APIGroup/UserLa entidad es propiedad del grupo
consumesApiComponentAPIEl componente usa una API
providesApiComponentAPIEl componente expone una API
dependsOnComponentComponent/ResourceEl componente depende de otro
dependencyOfComponent/ResourceComponentEs una dependencia de
partOfComponentSystemEl componente pertenece a un sistema
hasPartSystemComponentEl sistema contiene un componente
parentOfGroupGroupRelación de equipo padre
childOfGroupGroupRelación de equipo hijo
memberOfUserGroupEl usuario pertenece al grupo
hasMemberGroupUserEl grupo contiene al usuario
  1. Usa catalog-info.yaml en cada repositorio — asegúrate de que todos los servicios, bibliotecas y APIs estén registrados en el catálogo para tener visibilidad completa.

  2. Establece propiedad significativa — cada entidad debe tener un campo owner apuntando a un Group válido, habilitando responsabilidad y enrutamiento.

  3. Anota las entidades ricamente — agrega anotaciones para CI/CD, monitoreo, PagerDuty y documentación para hacer del catálogo un verdadero centro de información.

  4. Crea plantillas para caminos dorados — usa el scaffolder para definir formas estandarizadas de crear nuevos servicios, asegurando consistencia.

  5. Implementa TechDocs — mantén la documentación junto al código usando el plugin de TechDocs y mkdocs.yml para documentación viva.

  6. Usa GitHub discovery — configura github-discovery en las ubicaciones del catálogo para descubrir y registrar repositorios automáticamente.

  7. Modela tu organización — define Groups y Users para reflejar la estructura de tu equipo, habilitando seguimiento de propiedad y páginas de equipo.

  8. Mantén app-config.yaml consciente del entorno — usa app-config.local.yaml para desarrollo y variables de entorno para secretos de producción.

  9. Construye un ecosistema de plugins — crea plugins personalizados de frontend y backend para extender Backstage con las herramientas específicas de tu organización.

  10. Define Systems y Domains — modela la arquitectura de alto nivel usando Systems y Domains para dar a los desarrolladores un mapa de tu plataforma.