Backstage
Piattaforma open-source per portali sviluppatori interni di Spotify per la gestione del catalogo software e dell’esperienza sviluppatore.
Installazione
Sezione intitolata “Installazione”Creazione di una Nuova Applicazione
Sezione intitolata “Creazione di una Nuova Applicazione”| Comando | Descrizione |
|---|---|
npx @backstage/create-app@latest | Crea nuova applicazione Backstage |
npx @backstage/create-app@latest --skip-install | Crea app senza installare le dipendenze |
cd my-backstage-app && yarn install | Installa le dipendenze |
yarn dev | Avvia frontend e backend in modalita sviluppo |
yarn start | Avvia solo il frontend |
yarn start-backend | Avvia solo il backend |
yarn build:backend | Build del backend per produzione |
yarn build | Build di tutti i pacchetti |
node_modules/.bin/backstage-cli --version | Mostra la versione della CLI Backstage |
Distribuzione con Docker
Sezione intitolata “Distribuzione con Docker”| Comando | Descrizione |
|---|---|
yarn build:backend --config ../../app-config.yaml | Build del backend con configurazione |
docker build -t backstage -f packages/backend/Dockerfile . | Build dell’immagine Docker |
docker run -p 7007:7007 backstage | Esegui il container Backstage |
Comandi CLI
Sezione intitolata “Comandi CLI”Gestione dei Pacchetti
Sezione intitolata “Gestione dei Pacchetti”| Comando | Descrizione |
|---|---|
yarn backstage-cli package start | Avvia un pacchetto in modalita sviluppo |
yarn backstage-cli package build | Build di un pacchetto |
yarn backstage-cli package lint | Lint del codice sorgente del pacchetto |
yarn backstage-cli package test | Esegui i test del pacchetto |
yarn backstage-cli repo build --all | Build di tutti i pacchetti nel monorepo |
yarn backstage-cli repo lint --all | Lint di tutti i pacchetti |
yarn backstage-cli versions:bump | Aggiorna le dipendenze Backstage all’ultima versione |
yarn backstage-cli versions:bump --release next | Aggiorna alla pre-release successiva |
yarn backstage-cli migrate package-roles | Migra i pacchetti per usare i ruoli |
Creazione Plugin
Sezione intitolata “Creazione Plugin”| Comando | Descrizione |
|---|---|
yarn backstage-cli create-plugin | Crea nuovo plugin frontend |
yarn backstage-cli create-plugin --backend | Crea nuovo plugin backend |
yarn backstage-cli create-plugin --id my-plugin | Crea plugin con ID specifico |
yarn new | Crea componente interattivamente da template |
Catalogo Software
Sezione intitolata “Catalogo Software”Tipi di Entita
Sezione intitolata “Tipi di Entita”| Comando | Descrizione |
|---|---|
Aggiungi catalog-info.yaml alla root del repo | Registra componente nel catalogo |
kind: Component in catalog-info.yaml | Definisci un componente software |
kind: API in catalog-info.yaml | Definisci un’entita API |
kind: System in catalog-info.yaml | Definisci un raggruppamento di sistema |
kind: Domain in catalog-info.yaml | Definisci un dominio di business |
kind: Resource in catalog-info.yaml | Definisci una risorsa infrastrutturale |
kind: Group in catalog-info.yaml | Definisci un team/gruppo |
kind: User in catalog-info.yaml | Definisci un utente |
kind: Location in catalog-info.yaml | Referenzia altri file del catalogo |
Proprieta delle Entita
Sezione intitolata “Proprieta delle Entita”| Comando | Descrizione |
|---|---|
Imposta spec.owner: team-name | Imposta la proprieta dell’entita |
Imposta spec.lifecycle: production | Imposta la fase del ciclo di vita dell’entita |
Imposta spec.type: service | Imposta 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-name | Assegna a un sistema |
Imposta metadata.annotations per le integrazioni | Connetti a CI/CD, monitoraggio, ecc. |
Esempio catalog-info.yaml
Sezione intitolata “Esempio catalog-info.yaml”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
Esempio di Entita API
Sezione intitolata “Esempio di Entita API”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
Esempio di Sistema e Dominio
Sezione intitolata “Esempio di Sistema e Dominio”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
Template
Sezione intitolata “Template”Proprieta dei Template
Sezione intitolata “Proprieta dei Template”| Comando | Descrizione |
|---|---|
kind: Template in template.yaml | Definisci un template software |
Imposta spec.type: service | Il template crea un servizio |
Imposta spec.steps[] per le azioni del template | Definisci i passaggi di scaffolding |
action: fetch:template | Scarica e renderizza i file template |
action: publish:github | Pubblica repo scaffoldato su GitHub |
action: publish:github:pull-request | Crea PR invece di nuovo repo |
action: catalog:register | Registra entita creata nel catalogo |
action: github:actions:dispatch | Attiva workflow GitHub Actions |
Usa ${{ parameters.name }} nei template | Referenzia parametri di input dell’utente |
Imposta spec.parameters[] per i campi del form | Definisci il form di input del template |
Usa ui:widget: textarea nei parametri | Personalizza widget del campo del form |
Esempio di Definizione Template
Sezione intitolata “Esempio di Definizione Template”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 }}
Installazione Plugin
Sezione intitolata “Installazione Plugin”| Comando | Descrizione |
|---|---|
yarn add @backstage/plugin-catalog | Installa plugin catalogo |
yarn add @backstage/plugin-techdocs | Installa plugin TechDocs |
yarn add @backstage/plugin-kubernetes | Installa plugin Kubernetes |
yarn add @backstage/plugin-github-actions | Installa plugin GitHub Actions |
yarn add @backstage/plugin-search | Installa plugin ricerca |
yarn add @backstage/plugin-scaffolder | Installa plugin scaffolder |
yarn add @backstage/plugin-api-docs | Installa plugin documentazione API |
yarn add @backstage/plugin-cost-insights | Installa plugin analisi costi |
Registrazione Plugin
Sezione intitolata “Registrazione Plugin”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();
TechDocs
Sezione intitolata “TechDocs”Operazioni TechDocs
Sezione intitolata “Operazioni TechDocs”| Comando | Descrizione |
|---|---|
npx @techdocs/cli serve | Anteprima TechDocs in locale |
npx @techdocs/cli serve --docker-image techdocs-container | Servi usando immagine Docker personalizzata |
npx @techdocs/cli generate | Genera sito statico TechDocs |
npx @techdocs/cli generate --source-dir . | Genera da directory specifica |
npx @techdocs/cli publish --publisher-type googleGcs | Pubblica TechDocs su GCS |
npx @techdocs/cli publish --publisher-type awsS3 | Pubblica TechDocs su S3 |
Aggiungi annotazione backstage.io/techdocs-ref | Abilita TechDocs per l’entita |
Crea directory docs/ con mkdocs.yml | Configura sorgente TechDocs |
Imposta techdocs.builder: 'local' nel config | Usa builder TechDocs locale |
Imposta techdocs.builder: 'external' nel config | Usa builder CI/CD esterno |
Esempio mkdocs.yml per TechDocs
Sezione intitolata “Esempio mkdocs.yml per TechDocs”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
Ricerca
Sezione intitolata “Ricerca”Configurazione della Ricerca
Sezione intitolata “Configurazione della Ricerca”| Comando | Descrizione |
|---|---|
yarn add @backstage/plugin-search | Installa frontend di ricerca |
yarn add @backstage/plugin-search-backend | Installa backend di ricerca |
yarn add @backstage/plugin-search-backend-module-catalog | Aggiungi collator di ricerca del catalogo |
yarn add @backstage/plugin-search-backend-module-techdocs | Aggiungi collator di ricerca TechDocs |
Configura motore di ricerca in app-config.yaml | Configura Lunr, Elasticsearch o PgStore |
Imposta search.pg nel config | Usa PostgreSQL per la ricerca |
Imposta search.elasticsearch nel config | Usa Elasticsearch per la ricerca |
Configurazione
Sezione intitolata “Configurazione”Impostazioni Principali
Sezione intitolata “Impostazioni Principali”| Comando | Descrizione |
|---|---|
Modifica app-config.yaml | File di configurazione principale |
Modifica app-config.local.yaml | Override per sviluppo locale |
Modifica app-config.production.yaml | Configurazione di produzione |
Imposta app.baseUrl nel config | Configura URL del frontend |
Imposta backend.baseUrl nel config | Configura URL del backend |
Imposta backend.database nel config | Configura connessione al database |
Imposta backend.cors.origin nel config | Configura origini CORS |
Imposta auth.providers nel config | Configura provider di autenticazione |
Imposta catalog.locations[] nel config | Aggiungi sorgenti entita del catalogo |
Imposta catalog.rules[] nel config | Definisci regole di validazione delle entita |
Imposta integrations.github[] nel config | Configura token di integrazione GitHub |
Esempio app-config.yaml
Sezione intitolata “Esempio app-config.yaml”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}
Diagramma delle Relazioni tra Entita
Sezione intitolata “Diagramma delle Relazioni tra Entita”| Relazione | Da | A | Descrizione |
|---|---|---|---|
ownerOf | Group/User | Component/API | Il gruppo possiede l’entita |
ownedBy | Component/API | Group/User | L’entita e posseduta dal gruppo |
consumesApi | Component | API | Il componente usa un’API |
providesApi | Component | API | Il componente espone un’API |
dependsOn | Component | Component/Resource | Il componente dipende da un altro |
dependencyOf | Component/Resource | Component | E una dipendenza di |
partOf | Component | System | Il componente appartiene al sistema |
hasPart | System | Component | Il sistema contiene il componente |
parentOf | Group | Group | Relazione team genitore |
childOf | Group | Group | Relazione team figlio |
memberOf | User | Group | L’utente appartiene al gruppo |
hasMember | Group | User | Il gruppo contiene l’utente |
Buone Pratiche
Sezione intitolata “Buone Pratiche”-
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.
-
Imposta una proprieta significativa — ogni entita dovrebbe avere un campo
ownerche punta a un Group valido, abilitando la responsabilita e l’instradamento. -
Annota le entita in modo ricco — aggiungi annotazioni per CI/CD, monitoraggio, PagerDuty e documentazione per rendere il catalogo un vero hub.
-
Crea template per i percorsi golden — usa lo scaffolder per definire modi standardizzati di creare nuovi servizi, garantendo coerenza.
-
Implementa TechDocs — mantieni la documentazione insieme al codice usando il plugin TechDocs e
mkdocs.ymlper una documentazione sempre aggiornata. -
Usa GitHub discovery — configura
github-discoverynelle location del catalogo per scoprire e registrare automaticamente i repository. -
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.
-
Mantieni app-config.yaml sensibile all’ambiente — usa
app-config.local.yamlper lo sviluppo e variabili d’ambiente per i segreti di produzione. -
Costruisci un ecosistema di plugin — crea plugin frontend e backend personalizzati per estendere Backstage con gli strumenti specifici della tua organizzazione.
-
Definisci System e Domain — modella l’architettura di alto livello usando System e Domain per dare agli sviluppatori una mappa della tua piattaforma.