Veröffentlicht am

Backstage Developer Portal auf Kubernetes einrichten

Teilen:
Authors

TL;DR

  • Backstage ist ein Open-Source Internal Developer Portal von Spotify, das Software Catalog, Templates und TechDocs vereint
  • Der Software Catalog gibt Teams eine zentrale Uebersicht ueber alle Services, APIs und Infrastruktur-Komponenten
  • Software Templates ermoeglichen Self-Service: Entwickler erstellen neue Microservices per Klick mit Best Practices
  • TechDocs generiert automatisch Dokumentation aus Markdown-Dateien direkt im Portal
  • Backstage laesst sich per Helm Chart auf Kubernetes deployen und mit Plugins fuer ArgoCD, Kubernetes und PagerDuty erweitern

Platform Engineering mit Backstage: Internal Developer Portal auf Kubernetes

Wenn Ihr Platform-Engineering-Team staendig dieselben Fragen beantwortet - Wo laeuft Service X? Wie erstelle ich einen neuen Microservice? Wo ist die Doku? - dann brauchen Sie ein Internal Developer Portal. Backstage von Spotify ist die fuehrende Open-Source-Loesung dafuer.

In diesem Tutorial richten wir Backstage auf Kubernetes ein: vom Deployment ueber den Software Catalog bis zu Self-Service Templates.

Was ist Backstage?

Backstage ist eine Plattform fuer Internal Developer Portale. Es besteht aus drei Kernkomponenten:

┌─────────────────────────────────────────────────────┐
Backstage Portal├─────────────────┬─────────────────┬─────────────────┤
SoftwareSoftwareTechDocsCatalogTemplates      │                 │
│                 │                 │                 │
Alle ServicesSelf-ServiceAutomatischeAPIs, LibsScaffoldingDokumentation│  auf einen      │  fuer neue      │  aus MarkdownBlickProjekte       │                 │
├─────────────────┴─────────────────┴─────────────────┤
Plugin SystemKubernetes | ArgoCD | PagerDuty | Grafana | ...└─────────────────────────────────────────────────────┘

Vorteile:

  • Zentrale Uebersicht ueber alle Services und deren Eigentuemer
  • Self-Service fuer Entwickler (kein Ticket an Platform-Team noetig)
  • Einheitliche Dokumentation an einem Ort
  • Erweiterbares Plugin-System mit ueber 100 Community-Plugins

Teil 1: Backstage auf Kubernetes deployen

Voraussetzungen

# Kubernetes Cluster (ab 1.25)
kubectl version --short

# Helm installiert
helm version

# PostgreSQL-Datenbank (fuer Production)
# Backstage benoetigt eine Datenbank fuer den Catalog

Helm Chart Installation

# Backstage Helm Repository hinzufuegen
helm repo add backstage https://backstage.github.io/charts
helm repo update

# Namespace erstellen
kubectl create namespace backstage

Values-Datei vorbereiten

backstage-values.yaml:

backstage:
  image:
    registry: ghcr.io
    repository: backstage/backstage
    tag: latest

  extraEnvVars:
    - name: POSTGRES_HOST
      value: backstage-postgresql
    - name: POSTGRES_PORT
      value: "5432"
    - name: POSTGRES_USER
      valueFrom:
        secretKeyRef:
          name: backstage-db-credentials
          key: username
    - name: POSTGRES_PASSWORD
      valueFrom:
        secretKeyRef:
          name: backstage-db-credentials
          key: password

  appConfig:
    app:
      title: "Internal Developer Portal"
      baseUrl: https://backstage.example.de

    backend:
      baseUrl: https://backstage.example.de
      listen:
        port: 7007
      database:
        client: pg
        connection:
          host: ${POSTGRES_HOST}
          port: ${POSTGRES_PORT}
          user: ${POSTGRES_USER}
          password: ${POSTGRES_PASSWORD}

    catalog:
      import:
        entityFilename: catalog-info.yaml
      rules:
        - allow:
            - Component
            - System
            - API
            - Resource
            - Location
            - Template
      locations:
        - type: url
          target: https://github.com/myorg/backstage-catalog/blob/main/all-components.yaml

  resources:
    requests:
      cpu: 500m
      memory: 512Mi
    limits:
      cpu: 1000m
      memory: 1Gi

postgresql:
  enabled: true
  auth:
    existingSecret: backstage-db-credentials
  primary:
    persistence:
      enabled: true
      size: 10Gi

ingress:
  enabled: true
  className: nginx
  host: backstage.example.de
  tls:
    enabled: true
    secretName: backstage-tls

Datenbank-Secret erstellen und deployen

# Datenbank-Secret erstellen
kubectl create secret generic backstage-db-credentials \
  --namespace backstage \
  --from-literal=username=backstage \
  --from-literal=password=$(openssl rand -base64 24)

# Backstage installieren
helm install backstage backstage/backstage \
  --namespace backstage \
  --values backstage-values.yaml \
  --wait

# Status pruefen
kubectl get pods -n backstage

Erwartete Ausgabe:

NAME                         READY   STATUS    RESTARTS   AGE
backstage-6f8b9d7c4-x2k9m   1/1     Running   0          2m
backstage-postgresql-0       1/1     Running   0          2m

Teil 2: Software Catalog einrichten

Der Software Catalog ist das Herzsueck von Backstage. Jeder Service registriert sich ueber eine catalog-info.yaml.

Service im Catalog registrieren

Legen Sie im Root-Verzeichnis Ihres Repositories eine catalog-info.yaml an:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: payment-service
  description: "Zahlungsabwicklung fuer alle Bestellungen"
  annotations:
    backstage.io/techdocs-ref: dir:.
    github.com/project-slug: myorg/payment-service
    backstage.io/kubernetes-id: payment-service
    argocd/app-name: payment-service-prod
  tags:
    - java
    - spring-boot
    - payments
  links:
    - url: https://grafana.example.de/d/payment
      title: Grafana Dashboard
      icon: dashboard
spec:
  type: service
  lifecycle: production
  owner: team-payments
  system: order-platform
  providesApis:
    - payment-api
  consumesApis:
    - user-api
    - notification-api
  dependsOn:
    - resource:default/payment-database
---
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
  name: payment-api
  description: "REST API fuer Zahlungsabwicklung"
spec:
  type: openapi
  lifecycle: production
  owner: team-payments
  system: order-platform
  definition:
    $text: ./openapi.yaml

Teams und Systeme definieren

org.yaml fuer Ihre Organisation:

apiVersion: backstage.io/v1alpha1
kind: Group
metadata:
  name: team-payments
  description: "Payment-Team"
spec:
  type: team
  children: []
  members:
    - anna.schmidt
    - max.mueller
---
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
  name: order-platform
  description: "Bestell- und Zahlungsplattform"
spec:
  owner: team-payments
  domain: e-commerce

Catalog Discovery automatisieren

Anstatt jedes Repository einzeln zu registrieren, nutzen Sie GitHub Discovery:

# In backstage-values.yaml unter appConfig.catalog.providers
catalog:
  providers:
    github:
      myOrg:
        organization: 'myorg'
        catalogPath: '/catalog-info.yaml'
        filters:
          branch: 'main'
          repository: '.*'
        schedule:
          frequency:
            minutes: 30
          timeout:
            minutes: 3

Damit scannt Backstage automatisch alle Repositories in Ihrer GitHub-Organisation nach catalog-info.yaml Dateien.


Teil 3: Software Templates fuer Self-Service

Software Templates sind der groesste Produktivitaetsgewinn. Entwickler erstellen neue Services per Formular - mit allen Best Practices eingebaut.

Microservice-Template erstellen

templates/microservice/template.yaml:

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: microservice-template
  title: Neuen Microservice erstellen
  description: "Erstellt einen Spring Boot Microservice mit CI/CD, Monitoring und Kubernetes-Manifesten"
  tags:
    - java
    - spring-boot
    - kubernetes
spec:
  owner: team-platform
  type: service

  parameters:
    - title: Service-Informationen
      required:
        - name
        - description
        - owner
      properties:
        name:
          title: Service-Name
          type: string
          description: "Name des neuen Service (z.B. order-service)"
          pattern: '^[a-z0-9-]+$'
        description:
          title: Beschreibung
          type: string
        owner:
          title: Eigentuemer-Team
          type: string
          ui:field: OwnerPicker
          ui:options:
            catalogFilter:
              kind: Group

    - title: Technische Optionen
      properties:
        javaVersion:
          title: Java Version
          type: string
          default: "21"
          enum: ["17", "21"]
        database:
          title: Datenbank
          type: string
          default: postgresql
          enum:
            - postgresql
            - mysql
            - none
        port:
          title: Service Port
          type: number
          default: 8080

    - title: Repository
      required:
        - repoUrl
      properties:
        repoUrl:
          title: Repository-URL
          type: string
          ui:field: RepoUrlPicker
          ui:options:
            allowedHosts:
              - github.com

  steps:
    - id: fetch-template
      name: Skeleton generieren
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          description: ${{ parameters.description }}
          owner: ${{ parameters.owner }}
          javaVersion: ${{ parameters.javaVersion }}
          database: ${{ parameters.database }}
          port: ${{ parameters.port }}

    - id: publish
      name: Repository erstellen
      action: publish:github
      input:
        allowedHosts: ['github.com']
        repoUrl: ${{ parameters.repoUrl }}
        description: ${{ parameters.description }}
        defaultBranch: main
        repoVisibility: internal

    - id: register
      name: Im Catalog registrieren
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }}
        catalogInfoPath: '/catalog-info.yaml'

  output:
    links:
      - title: Repository
        url: ${{ steps['publish'].output.remoteUrl }}
      - title: Im Catalog oeffnen
        icon: catalog
        entityRef: ${{ steps['register'].output.entityRef }}

Skeleton-Dateien (Template-Inhalte)

templates/microservice/skeleton/catalog-info.yaml:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: ${{ values.name }}
  description: ${{ values.description }}
  annotations:
    backstage.io/techdocs-ref: dir:.
    github.com/project-slug: myorg/${{ values.name }}
    backstage.io/kubernetes-id: ${{ values.name }}
spec:
  type: service
  lifecycle: experimental
  owner: ${{ values.owner }}

templates/microservice/skeleton/k8s/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ${{ values.name }}
  labels:
    app: ${{ values.name }}
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ${{ values.name }}
  template:
    metadata:
      labels:
        app: ${{ values.name }}
    spec:
      containers:
        - name: ${{ values.name }}
          image: ghcr.io/myorg/${{ values.name }}:latest
          ports:
            - containerPort: ${{ values.port }}
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 500m
              memory: 512Mi
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: ${{ values.port }}
            initialDelaySeconds: 30
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: ${{ values.port }}
            initialDelaySeconds: 10

Teil 4: TechDocs einrichten

TechDocs generiert automatisch Dokumentation aus Markdown-Dateien und zeigt sie direkt im Portal an.

MkDocs-Konfiguration im Service-Repo

mkdocs.yml im Root-Verzeichnis jedes Service:

site_name: payment-service
nav:
  - Home: index.md
  - Architecture: architecture.md
  - API: api.md
  - Runbook: runbook.md

plugins:
  - techdocs-core

Dokumentation schreiben

docs/index.md:

# Payment Service

## Uebersicht
Der Payment Service verarbeitet alle Zahlungstransaktionen.

## Schnellstart
1. Repository klonen
2. `./gradlew bootRun` ausfuehren
3. API unter http://localhost:8080/swagger-ui verfuegbar

## Kontakt
Team Payments - Slack: #team-payments

TechDocs Builder konfigurieren

In der Backstage-Konfiguration:

# In backstage-values.yaml unter appConfig
techdocs:
  builder: 'external'
  generator:
    runIn: 'local'
  publisher:
    type: 'awsS3'
    awsS3:
      bucketName: backstage-techdocs
      region: eu-central-1

Fuer kleinere Setups reicht auch die lokale Variante:

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

Teil 5: Plugins fuer den Praxiseinsatz

Backstage wird durch Plugins richtig maechtig. Hier die wichtigsten fuer Kubernetes-Teams.

Kubernetes Plugin

Zeigt Pod-Status, Logs und Events direkt im Portal:

# In backstage-values.yaml unter appConfig
kubernetes:
  serviceLocatorMethod:
    type: 'multiTenant'
  clusterLocatorMethods:
    - type: 'config'
      clusters:
        - url: https://kubernetes.default.svc
          name: production
          authProvider: 'serviceAccount'
          skipTLSVerify: false
          serviceAccountToken: ${K8S_SA_TOKEN}
          dashboardUrl: https://dashboard.example.de
          dashboardApp: standard

Damit sehen Entwickler in Backstage direkt:

  • Welche Pods laufen fuer ihren Service
  • CPU/Memory-Verbrauch
  • Aktuelle Events und Fehler

ArgoCD Plugin

Verknuepft Services mit ihren ArgoCD-Applications:

# In backstage-values.yaml unter appConfig
argocd:
  baseUrl: https://argocd.example.de
  username: backstage-readonly
  password: ${ARGOCD_PASSWORD}

Die Annotation im catalog-info.yaml verbindet beides:

metadata:
  annotations:
    argocd/app-name: payment-service-prod

PagerDuty Plugin

Zeigt On-Call-Informationen und offene Incidents:

metadata:
  annotations:
    pagerduty.com/service-id: P1234AB

Teil 6: Wann Backstage, wann Alternativen?

Backstage ist maechtig, aber nicht immer die richtige Wahl.

Backstage ist ideal wenn:

  • Ihr Unternehmen hat mehr als 50 Microservices
  • Mehrere Teams arbeiten unabhaengig voneinander
  • Sie ein dediziertes Platform-Team haben (mindestens 2-3 Personen)
  • Self-Service und Standardisierung sind wichtig
  • Sie bereits ein Plugin-Oekosystem nutzen wollen

Einfachere Alternativen bei kleinen Teams:

KriteriumBackstagePortEinfache Wiki-Loesung
Team-GroesseAb 5 TeamsAb 3 Teams1-3 Teams
Setup-Aufwand2-4 Wochen1 Tag (SaaS)1 Stunde
WartungHoch (eigenes Team)Niedrig (SaaS)Minimal
AnpassbarkeitSehr hochMittelNiedrig
KostenInfrastructure + TeamLizenzkostenFast kostenlos
Self-ServiceVoll (Templates)Ja (Actions)Nein

Faustregel: Unter 5 Teams und 20 Services lohnt sich Backstage selten. Ab 10 Teams wird es fast unverzichtbar.


Teil 7: Praktische Implementierung Schritt fuer Schritt

Woche 1-2: Grundlagen

# Tag 1-2: Backstage auf Kubernetes deployen
helm install backstage backstage/backstage \
  --namespace backstage \
  --values backstage-values.yaml

# Tag 3-5: Erste Services im Catalog registrieren
# catalog-info.yaml in 5-10 wichtigsten Repos erstellen
# GitHub Discovery aktivieren

# Tag 6-10: Teams und Systeme modellieren
# org.yaml mit allen Teams pflegen
# Systeme und Domains definieren

Woche 3-4: Self-Service und Doku

# Tag 11-15: Erstes Software Template erstellen
# Microservice-Template wie oben gezeigt
# Template testen und iterieren

# Tag 16-20: TechDocs einrichten
# mkdocs.yml in wichtigsten Repos
# Runbooks und Architecture-Docs migrieren

Woche 5-6: Plugins und Rollout

# Kubernetes und ArgoCD Plugins konfigurieren
# PagerDuty oder Opsgenie anbinden
# Onboarding-Session fuer alle Entwickler
# Feedback sammeln und iterieren

Erfolg messen

Tracken Sie diese Metriken:

Vorher vs. Nachher:
- Zeit fuer neuen Service:    2 Tage  ->  15 Minuten
- Onboarding neuer Entwickler: 1 Woche ->  1 Tag
- "Wo laeuft Service X?":     Slack   ->  Catalog-Suche
- Dokumentation aktuell:       30%     ->  80%+

Zusammenfassung

KomponenteFunktionAufwand
Software CatalogUebersicht aller Services1-2 Tage
Software TemplatesSelf-Service Scaffolding3-5 Tage
TechDocsAutomatische Dokumentation1-2 Tage
Kubernetes PluginPod-Status im Portal2-4 Stunden
ArgoCD PluginDeployment-Status1-2 Stunden

Backstage auf Kubernetes ist ein Investment, das sich ab einer gewissen Teamgroesse definitiv auszahlt. Starten Sie klein mit dem Software Catalog, fuegen Sie Templates hinzu und erweitern Sie schrittweise mit Plugins.


Verwandte Artikel


Sie moechten ein Internal Developer Portal aufbauen, wissen aber nicht wo anfangen? Wir helfen bei Konzeption, Setup und Rollout von Backstage auf Kubernetes - von der Architektur bis zum Onboarding Ihrer Teams. Jetzt Beratung anfragen.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen