Salta ai contenuti

Backstage

Piattaforma open-source per portali sviluppatori interni di Spotify per la gestione del catalogo software e dell’esperienza sviluppatore.

ComandoDescrizione
npx @backstage/create-app@latestCrea nuova applicazione Backstage
npx @backstage/create-app@latest --skip-installCrea app senza installare le dipendenze
cd my-backstage-app && yarn installInstalla le dipendenze
yarn devAvvia frontend e backend in modalita sviluppo
yarn startAvvia solo il frontend
yarn start-backendAvvia solo il backend
yarn build:backendBuild del backend per produzione
yarn buildBuild di tutti i pacchetti
node_modules/.bin/backstage-cli --versionMostra la versione della CLI Backstage
ComandoDescrizione
yarn build:backend --config ../../app-config.yamlBuild del backend con configurazione
docker build -t backstage -f packages/backend/Dockerfile .Build dell’immagine Docker
docker run -p 7007:7007 backstageEsegui il container Backstage
ComandoDescrizione
yarn backstage-cli package startAvvia un pacchetto in modalita sviluppo
yarn backstage-cli package buildBuild di un pacchetto
yarn backstage-cli package lintLint del codice sorgente del pacchetto
yarn backstage-cli package testEsegui i test del pacchetto
yarn backstage-cli repo build --allBuild di tutti i pacchetti nel monorepo
yarn backstage-cli repo lint --allLint di tutti i pacchetti
yarn backstage-cli versions:bumpAggiorna le dipendenze Backstage all’ultima versione
yarn backstage-cli versions:bump --release nextAggiorna alla pre-release successiva
yarn backstage-cli migrate package-rolesMigra i pacchetti per usare i ruoli
ComandoDescrizione
yarn backstage-cli create-pluginCrea nuovo plugin frontend
yarn backstage-cli create-plugin --backendCrea nuovo plugin backend
yarn backstage-cli create-plugin --id my-pluginCrea plugin con ID specifico
yarn newCrea componente interattivamente da template
ComandoDescrizione
Aggiungi catalog-info.yaml alla root del repoRegistra componente nel catalogo
kind: Component in catalog-info.yamlDefinisci un componente software
kind: API in catalog-info.yamlDefinisci un’entita API
kind: System in catalog-info.yamlDefinisci un raggruppamento di sistema
kind: Domain in catalog-info.yamlDefinisci un dominio di business
kind: Resource in catalog-info.yamlDefinisci una risorsa infrastrutturale
kind: Group in catalog-info.yamlDefinisci un team/gruppo
kind: User in catalog-info.yamlDefinisci un utente
kind: Location in catalog-info.yamlReferenzia altri file del catalogo
ComandoDescrizione
Imposta spec.owner: team-nameImposta la proprieta dell’entita
Imposta spec.lifecycle: productionImposta la fase del ciclo di vita dell’entita
Imposta spec.type: serviceImposta il tipo di componente (service, website, library)
Imposta spec.dependsOn: ['component:other']Definisci le dipendenze
Imposta spec.providesApis: ['api-name']Dichiara API fornite
Imposta spec.consumesApis: ['api-name']Dichiara API consumate
Imposta spec.system: system-nameAssegna a un sistema
Imposta metadata.annotations per le integrazioniConnetti a CI/CD, monitoraggio, ecc.
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
ComandoDescrizione
kind: Template in template.yamlDefinisci un template software
Imposta spec.type: serviceIl template crea un servizio
Imposta spec.steps[] per le azioni del templateDefinisci i passaggi di scaffolding
action: fetch:templateScarica e renderizza i file template
action: publish:githubPubblica repo scaffoldato su GitHub
action: publish:github:pull-requestCrea PR invece di nuovo repo
action: catalog:registerRegistra entita creata nel catalogo
action: github:actions:dispatchAttiva workflow GitHub Actions
Usa ${{ parameters.name }} nei templateReferenzia parametri di input dell’utente
Imposta spec.parameters[] per i campi del formDefinisci il form di input del template
Usa ui:widget: textarea nei parametriPersonalizza widget del campo del form
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 }}
ComandoDescrizione
yarn add @backstage/plugin-catalogInstalla plugin catalogo
yarn add @backstage/plugin-techdocsInstalla plugin TechDocs
yarn add @backstage/plugin-kubernetesInstalla plugin Kubernetes
yarn add @backstage/plugin-github-actionsInstalla plugin GitHub Actions
yarn add @backstage/plugin-searchInstalla plugin ricerca
yarn add @backstage/plugin-scaffolderInstalla plugin scaffolder
yarn add @backstage/plugin-api-docsInstalla plugin documentazione API
yarn add @backstage/plugin-cost-insightsInstalla plugin analisi costi

Registra i plugin frontend in 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>
);

Registra i plugin backend in 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();
ComandoDescrizione
npx @techdocs/cli serveAnteprima TechDocs in locale
npx @techdocs/cli serve --docker-image techdocs-containerServi usando immagine Docker personalizzata
npx @techdocs/cli generateGenera sito statico TechDocs
npx @techdocs/cli generate --source-dir .Genera da directory specifica
npx @techdocs/cli publish --publisher-type googleGcsPubblica TechDocs su GCS
npx @techdocs/cli publish --publisher-type awsS3Pubblica TechDocs su S3
Aggiungi annotazione backstage.io/techdocs-refAbilita TechDocs per l’entita
Crea directory docs/ con mkdocs.ymlConfigura sorgente TechDocs
Imposta techdocs.builder: 'local' nel configUsa builder TechDocs locale
Imposta techdocs.builder: 'external' nel configUsa builder CI/CD esterno
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
ComandoDescrizione
yarn add @backstage/plugin-searchInstalla frontend di ricerca
yarn add @backstage/plugin-search-backendInstalla backend di ricerca
yarn add @backstage/plugin-search-backend-module-catalogAggiungi collator di ricerca del catalogo
yarn add @backstage/plugin-search-backend-module-techdocsAggiungi collator di ricerca TechDocs
Configura motore di ricerca in app-config.yamlConfigura Lunr, Elasticsearch o PgStore
Imposta search.pg nel configUsa PostgreSQL per la ricerca
Imposta search.elasticsearch nel configUsa Elasticsearch per la ricerca
ComandoDescrizione
Modifica app-config.yamlFile di configurazione principale
Modifica app-config.local.yamlOverride per sviluppo locale
Modifica app-config.production.yamlConfigurazione di produzione
Imposta app.baseUrl nel configConfigura URL del frontend
Imposta backend.baseUrl nel configConfigura URL del backend
Imposta backend.database nel configConfigura connessione al database
Imposta backend.cors.origin nel configConfigura origini CORS
Imposta auth.providers nel configConfigura provider di autenticazione
Imposta catalog.locations[] nel configAggiungi sorgenti entita del catalogo
Imposta catalog.rules[] nel configDefinisci regole di validazione delle entita
Imposta integrations.github[] nel configConfigura token di integrazione 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}
RelazioneDaADescrizione
ownerOfGroup/UserComponent/APIIl gruppo possiede l’entita
ownedByComponent/APIGroup/UserL’entita e posseduta dal gruppo
consumesApiComponentAPIIl componente usa un’API
providesApiComponentAPIIl componente espone un’API
dependsOnComponentComponent/ResourceIl componente dipende da un altro
dependencyOfComponent/ResourceComponentE una dipendenza di
partOfComponentSystemIl componente appartiene al sistema
hasPartSystemComponentIl sistema contiene il componente
parentOfGroupGroupRelazione team genitore
childOfGroupGroupRelazione team figlio
memberOfUserGroupL’utente appartiene al gruppo
hasMemberGroupUserIl gruppo contiene l’utente
  1. Usa catalog-info.yaml in ogni repository — assicurati che tutti i servizi, le librerie e le API siano registrati nel catalogo per una visibilita completa.

  2. Imposta una proprieta significativa — ogni entita dovrebbe avere un campo owner che punta a un Group valido, abilitando la responsabilita e l’instradamento.

  3. Annota le entita in modo ricco — aggiungi annotazioni per CI/CD, monitoraggio, PagerDuty e documentazione per rendere il catalogo un vero hub.

  4. Crea template per i percorsi golden — usa lo scaffolder per definire modi standardizzati di creare nuovi servizi, garantendo coerenza.

  5. Implementa TechDocs — mantieni la documentazione insieme al codice usando il plugin TechDocs e mkdocs.yml per una documentazione sempre aggiornata.

  6. Usa GitHub discovery — configura github-discovery nelle location del catalogo per scoprire e registrare automaticamente i repository.

  7. Modella la tua organizzazione — definisci Group e User per riflettere la struttura del tuo team, abilitando il tracciamento della proprieta e le pagine dei team.

  8. Mantieni app-config.yaml sensibile all’ambiente — usa app-config.local.yaml per lo sviluppo e variabili d’ambiente per i segreti di produzione.

  9. Costruisci un ecosistema di plugin — crea plugin frontend e backend personalizzati per estendere Backstage con gli strumenti specifici della tua organizzazione.

  10. Definisci System e Domain — modella l’architettura di alto livello usando System e Domain per dare agli sviluppatori una mappa della tua piattaforma.