Zum Inhalt springen

Backstage

Open-Source-Plattform für interne Entwicklerportale von Spotify zur Verwaltung von Software-Katalogen und der Developer Experience.

BefehlBeschreibung
npx @backstage/create-app@latestNeue Backstage-Anwendung erstellen
npx @backstage/create-app@latest --skip-installApp ohne Abhängigkeiten installieren erstellen
cd my-backstage-app && yarn installAbhängigkeiten installieren
yarn devFrontend und Backend im Entwicklungsmodus starten
yarn startNur Frontend starten
yarn start-backendNur Backend starten
yarn build:backendBackend für Produktion bauen
yarn buildAlle Pakete bauen
node_modules/.bin/backstage-cli --versionBackstage CLI-Version anzeigen
BefehlBeschreibung
yarn build:backend --config ../../app-config.yamlBackend mit Konfiguration bauen
docker build -t backstage -f packages/backend/Dockerfile .Docker-Image bauen
docker run -p 7007:7007 backstageBackstage-Container ausführen
BefehlBeschreibung
yarn backstage-cli package startPaket im Entwicklungsmodus starten
yarn backstage-cli package buildPaket bauen
yarn backstage-cli package lintPaket-Quellcode linten
yarn backstage-cli package testPaket-Tests ausführen
yarn backstage-cli repo build --allAlle Pakete im Monorepo bauen
yarn backstage-cli repo lint --allAlle Pakete linten
yarn backstage-cli versions:bumpBackstage-Abhängigkeiten auf neueste Version aktualisieren
yarn backstage-cli versions:bump --release nextAuf nächstes Pre-Release aktualisieren
yarn backstage-cli migrate package-rolesPakete zur Verwendung von Rollen migrieren
BefehlBeschreibung
yarn backstage-cli create-pluginNeues Frontend-Plugin erstellen
yarn backstage-cli create-plugin --backendNeues Backend-Plugin erstellen
yarn backstage-cli create-plugin --id my-pluginPlugin mit bestimmter ID erstellen
yarn newInteraktiv Komponente aus Vorlage erstellen
BefehlBeschreibung
catalog-info.yaml zum Repo-Root hinzufügenKomponente im Katalog registrieren
kind: Component in catalog-info.yamlSoftware-Komponente definieren
kind: API in catalog-info.yamlAPI-Entity definieren
kind: System in catalog-info.yamlSystem-Gruppierung definieren
kind: Domain in catalog-info.yamlBusiness-Domain definieren
kind: Resource in catalog-info.yamlInfrastruktur-Ressource definieren
kind: Group in catalog-info.yamlTeam/Gruppe definieren
kind: User in catalog-info.yamlBenutzer definieren
kind: Location in catalog-info.yamlAndere Katalog-Dateien referenzieren
BefehlBeschreibung
spec.owner: team-name setzenEntity-Eigentümer festlegen
spec.lifecycle: production setzenEntity-Lifecycle-Phase festlegen
spec.type: service setzenKomponententyp festlegen (service, website, library)
spec.dependsOn: ['component:other'] setzenAbhängigkeiten definieren
spec.providesApis: ['api-name'] setzenBereitgestellte APIs deklarieren
spec.consumesApis: ['api-name'] setzenKonsumierte APIs deklarieren
spec.system: system-name setzenEinem System zuweisen
metadata.annotations für Integrationen setzenMit CI/CD, Monitoring etc. verbinden
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
BefehlBeschreibung
kind: Template in template.yamlSoftware-Template definieren
spec.type: service setzenTemplate erstellt einen Service
spec.steps[] für Template-Aktionen setzenScaffolding-Schritte definieren
action: fetch:templateTemplate-Dateien abrufen und rendern
action: publish:githubErstelltes Repo auf GitHub veröffentlichen
action: publish:github:pull-requestPR statt neuem Repo erstellen
action: catalog:registerErstellte Entity im Katalog registrieren
action: github:actions:dispatchGitHub Actions Workflow auslösen
${{ parameters.name }} in Templates verwendenBenutzereingabe-Parameter referenzieren
spec.parameters[] für Formularfelder setzenTemplate-Eingabeformular definieren
ui:widget: textarea in Parametern verwendenFormularfeld-Widget anpassen
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 }}
BefehlBeschreibung
yarn add @backstage/plugin-catalogKatalog-Plugin installieren
yarn add @backstage/plugin-techdocsTechDocs-Plugin installieren
yarn add @backstage/plugin-kubernetesKubernetes-Plugin installieren
yarn add @backstage/plugin-github-actionsGitHub Actions-Plugin installieren
yarn add @backstage/plugin-searchSuch-Plugin installieren
yarn add @backstage/plugin-scaffolderScaffolder-Plugin installieren
yarn add @backstage/plugin-api-docsAPI-Docs-Plugin installieren
yarn add @backstage/plugin-cost-insightsCost-Insights-Plugin installieren

Frontend-Plugins in packages/app/src/App.tsx registrieren:

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>
);

Backend-Plugins in packages/backend/src/index.ts registrieren:

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();
BefehlBeschreibung
npx @techdocs/cli serveTechDocs lokal voranzeigen
npx @techdocs/cli serve --docker-image techdocs-containerMit benutzerdefiniertem Docker-Image bereitstellen
npx @techdocs/cli generateStatische TechDocs-Site generieren
npx @techdocs/cli generate --source-dir .Aus bestimmtem Verzeichnis generieren
npx @techdocs/cli publish --publisher-type googleGcsTechDocs nach GCS veröffentlichen
npx @techdocs/cli publish --publisher-type awsS3TechDocs nach S3 veröffentlichen
backstage.io/techdocs-ref-Annotation hinzufügenTechDocs für Entity aktivieren
docs/-Verzeichnis mit mkdocs.yml erstellenTechDocs-Quelle einrichten
techdocs.builder: 'local' in Konfiguration setzenLokalen TechDocs-Builder verwenden
techdocs.builder: 'external' in Konfiguration setzenExternen CI/CD-Builder verwenden
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
BefehlBeschreibung
yarn add @backstage/plugin-searchSuch-Frontend installieren
yarn add @backstage/plugin-search-backendSuch-Backend installieren
yarn add @backstage/plugin-search-backend-module-catalogKatalog-Such-Collator hinzufügen
yarn add @backstage/plugin-search-backend-module-techdocsTechDocs-Such-Collator hinzufügen
Suchmaschine in app-config.yaml konfigurierenLunr, Elasticsearch oder PgStore einrichten
search.pg in Konfiguration setzenPostgreSQL für Suche verwenden
search.elasticsearch in Konfiguration setzenElasticsearch für Suche verwenden
BefehlBeschreibung
app-config.yaml bearbeitenHauptkonfigurationsdatei
app-config.local.yaml bearbeitenLokale Entwicklungsüberschreibungen
app-config.production.yaml bearbeitenProduktionskonfiguration
app.baseUrl in Konfiguration setzenFrontend-URL konfigurieren
backend.baseUrl in Konfiguration setzenBackend-URL konfigurieren
backend.database in Konfiguration setzenDatenbankverbindung konfigurieren
backend.cors.origin in Konfiguration setzenCORS-Origins konfigurieren
auth.providers in Konfiguration setzenAuthentifizierungs-Provider konfigurieren
catalog.locations[] in Konfiguration setzenKatalog-Entity-Quellen hinzufügen
catalog.rules[] in Konfiguration setzenEntity-Validierungsregeln definieren
integrations.github[] in Konfiguration setzenGitHub-Integrations-Token konfigurieren
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}
BeziehungVonZuBeschreibung
ownerOfGroup/UserComponent/APIGruppe besitzt die Entity
ownedByComponent/APIGroup/UserEntity gehört der Gruppe
consumesApiComponentAPIKomponente nutzt eine API
providesApiComponentAPIKomponente stellt eine API bereit
dependsOnComponentComponent/ResourceKomponente hängt von anderer ab
dependencyOfComponent/ResourceComponentIst Abhängigkeit von
partOfComponentSystemKomponente gehört zu System
hasPartSystemComponentSystem enthält Komponente
parentOfGroupGroupÜbergeordnete Team-Beziehung
childOfGroupGroupUntergeordnete Team-Beziehung
memberOfUserGroupBenutzer gehört zur Gruppe
hasMemberGroupUserGruppe enthält Benutzer
  1. catalog-info.yaml in jedem Repository verwenden — Sicherstellen, dass alle Services, Bibliotheken und APIs im Katalog registriert sind, für vollständige Sichtbarkeit.

  2. Sinnvolle Eigentümerschaft festlegen — Jede Entity sollte ein owner-Feld haben, das auf eine gültige Gruppe verweist, um Verantwortlichkeit und Routing zu ermöglichen.

  3. Entities reichhaltig annotieren — Annotationen für CI/CD, Monitoring, PagerDuty und Dokumentation hinzufügen, um den Katalog zu einem echten Zentrum zu machen.

  4. Templates für Golden Paths erstellen — Den Scaffolder verwenden, um standardisierte Wege zur Erstellung neuer Services zu definieren und Konsistenz sicherzustellen.

  5. TechDocs implementieren — Dokumentation neben dem Code pflegen mit dem TechDocs-Plugin und mkdocs.yml für lebende Dokumentation.

  6. GitHub Discovery verwendengithub-discovery in Katalog-Locations konfigurieren, um Repositories automatisch zu entdecken und zu registrieren.

  7. Organisation modellieren — Groups und Users definieren, die die Teamstruktur widerspiegeln, um Eigentümer-Tracking und Team-Seiten zu ermöglichen.

  8. app-config.yaml umgebungsbewusst haltenapp-config.local.yaml für Entwicklung und Umgebungsvariablen für Produktionsgeheimnisse verwenden.

  9. Plugin-Ökosystem aufbauen — Benutzerdefinierte Frontend- und Backend-Plugins erstellen, um Backstage mit den spezifischen Tools der Organisation zu erweitern.

  10. Systems und Domains definieren — Die übergeordnete Architektur mit Systems und Domains modellieren, um Entwicklern eine Karte der Plattform zu geben.