🔴 Advanced

Internal Developer Portals — Backstage a alternatívy

Internal Developer Portal (IDP) je centrálny vstupný bod, cez ktorý vývojári pristupujú ku všetkým službám, nástrojom, dokumentácii a infraštruktúre v organizácii. Tento článok nadväzuje na Platform Engineering a podrobne rozoberá developer portály — od Backstage po komerčné alternatívy.


Prečo vznikli developer portály?

S rastom počtu mikroslužieb, tímov a nástrojov sa vývojári stretávajú s problémom kognitívnej záťaže:

  • Kde nájdem dokumentáciu k payment-service?
  • Kto vlastní user-api a koho mám kontaktovať pri incidente?
  • Ako vytvorím nový microservice podľa firemných štandardov?
  • Kde vidím stav deploymentu mojej služby?
  • Aké závislosti má moja služba?

Vývojári trávia až 30 % času hľadaním informácií namiesto písania kódu. Toto sa nazýva developer experience (DevEx) problém.

Čo developer portál rieši

BEZ PORTÁLU:                          S PORTÁLOM:
┌──────────┐  ┌──────────┐           ┌─────────────────────┐
│  GitHub   │  │  Jira    │           │  Developer Portal   │
├──────────┤  ├──────────┤           │                     │
│ Confluence│  │ Grafana  │    →      │  📋 Service Catalog │
├──────────┤  ├──────────┤           │  📝 Dokumentácia    │
│ PagerDuty│  │ ArgoCD   │           │  🚀 Self-service    │
├──────────┤  ├──────────┤           │  📊 Monitoring      │
│ Terraform│  │  Slack   │           │  🔗 Všetko na 1 mieste│
└──────────┘  └──────────┘           └─────────────────────┘
  10+ nástrojov, žiadny prehľad       1 portál, plný kontext

Backstage — Open-source developer portal

Backstage je open-source platforma vytvorená v Spotify v roku 2016 a open-sourcovaná v roku 2020. Od roku 2022 je CNCF Incubating projekt. Je de facto štandardom pre developer portály.

Architektúra Backstage

┌────────────────────────────────────────────┐
│              Frontend (React)              │
│  ┌────────┐ ┌────────┐ ┌────────────────┐ │
│  │Catalog │ │TechDocs│ │  Plugin UI     │ │
│  │  UI    │ │  UI    │ │(K8s, CI/CD...) │ │
│  └────────┘ └────────┘ └────────────────┘ │
├────────────────────────────────────────────┤
│              Backend (Node.js)             │
│  ┌────────────┐ ┌──────────┐ ┌──────────┐ │
│  │ Catalog API│ │Scaffolder│ │ Auth     │ │
│  │            │ │ API      │ │ Provider │ │
│  └────────────┘ └──────────┘ └──────────┘ │
├────────────────────────────────────────────┤
│          PostgreSQL Database               │
└────────────────────────────────────────────┘
         │              │
    ┌────┴────┐    ┌────┴────┐
    │ GitHub  │    │ K8s API │
    │ GitLab  │    │ CI/CD   │
    └─────────┘    └─────────┘

Core features

Feature Popis
Software Catalog Centrálny register všetkých komponentov, služieb, API a zdrojov
Software Templates Scaffolding nových projektov podľa štandardov
TechDocs Dokumentácia ako kód (Markdown → portál)
Search Fulltextové vyhľadávanie naprieč celým portálom
Plugins 200+ community pluginov pre integrácie
Auth SSO cez GitHub, Google, Okta, LDAP a ďalšie

Inštalácia Backstage

# Vytvorenie novej Backstage inštancie
npx @backstage/create-app@latest

# Štruktúra projektu
my-backstage/
├── app-config.yaml          # Hlavná konfigurácia
├── packages/
│   ├── app/                 # Frontend (React)
│   └── backend/             # Backend (Node.js)
├── plugins/                 # Vlastné pluginy
└── catalog-info.yaml        # Self-registration

# Spustenie
cd my-backstage
yarn dev

Konfigurácia — app-config.yaml

app:
  title: My Company Developer Portal
  baseUrl: http://localhost:3000

backend:
  baseUrl: http://localhost:7007
  database:
    client: pg
    connection:
      host: localhost
      port: 5432
      user: backstage
      password: ${POSTGRES_PASSWORD}

auth:
  providers:
    github:
      development:
        clientId: ${GITHUB_CLIENT_ID}
        clientSecret: ${GITHUB_CLIENT_SECRET}

catalog:
  locations:
    - type: url
      target: https://github.com/myorg/services/blob/main/catalog-info.yaml
    - type: url
      target: https://github.com/myorg/backstage-templates/blob/main/all-templates.yaml

integrations:
  github:
    - host: github.com
      token: ${GITHUB_TOKEN}

Service Catalog

Service Catalog je srdcom Backstage. Poskytuje centrálny prehľad o všetkých komponentoch v organizácii.

Registrácia služby — catalog-info.yaml

Každá služba má v root adresári súbor catalog-info.yaml:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: order-service
  description: Služba na správu objednávok
  annotations:
    github.com/project-slug: myorg/order-service
    backstage.io/techdocs-ref: dir:.
    pagerduty.com/service-id: P1234AB
    grafana/dashboard-selector: "app=order-service"
  tags:
    - python
    - fastapi
    - grpc
  links:
    - url: https://grafana.internal/d/orders
      title: Grafana Dashboard
    - url: https://runbooks.internal/order-service
      title: Runbook
spec:
  type: service
  lifecycle: production
  owner: team-orders
  system: e-commerce
  dependsOn:
    - component:inventory-service
    - component:payment-service
    - resource:orders-db
    - resource:orders-redis
  providesApis:
    - orders-api
  consumesApis:
    - payments-api
    - inventory-api

Entity typy v katalógu

Kind Popis Príklad
Component Softvérový komponent (služba, knižnica, website) order-service
API API definícia (OpenAPI, AsyncAPI, gRPC) orders-api
Resource Infraštruktúrny zdroj orders-db, redis-cache
System Skupina súvisiacich komponentov e-commerce
Domain Biznis doména retail, logistics
Group Tím alebo organizačná jednotka team-orders
User Používateľ john.doe

API definícia

apiVersion: backstage.io/v1alpha1
kind: API
metadata:
  name: orders-api
  description: REST API pre správu objednávok
spec:
  type: openapi
  lifecycle: production
  owner: team-orders
  system: e-commerce
  definition:
    $text: ./openapi.yaml

Dependency tracking

Backstage automaticky vizualizuje závislosti medzi komponentmi:

┌──────────┐     ┌───────────────┐     ┌─────────────┐
│ Frontend │────→│ Order Service │────→│Payment Svc  │
│   App    │     │               │     │             │
└──────────┘     └───────┬───────┘     └─────────────┘
                         │
                    ┌────┴────┐
                    │Orders DB│
                    │(Postgres)│
                    └─────────┘

Toto umožňuje:

  • Impact analysis — čo sa stane, ak spadne inventory-service?
  • Ownership clarity — kto je zodpovedný za každý komponent?
  • Audit trail — kedy bola služba registrovaná, kto ju vlastní?

Software Templates (Scaffolder)

Scaffolder umožňuje vytvárať self-service šablóny pre nové projekty. Vývojár vyplní formulár a Backstage automaticky vytvorí repozitár, CI/CD pipeline, infraštruktúru a registráciu v katalógu.

Príklad šablóny — Node.js Microservice

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: nodejs-microservice
  title: Node.js Microservice
  description: Vytvorí nový Node.js microservice s Express, CI/CD a monitoring
  tags:
    - nodejs
    - express
    - recommended
spec:
  owner: platform-team
  type: service

  parameters:
    - title: Informácie o službe
      required:
        - name
        - owner
        - system
      properties:
        name:
          title: Názov služby
          type: string
          pattern: '^[a-z][a-z0-9-]*$'
          ui:autofocus: true
        description:
          title: Popis
          type: string
        owner:
          title: Vlastník (tím)
          type: string
          ui:field: OwnerPicker
          ui:options:
            catalogFilter:
              kind: Group
        system:
          title: Systém
          type: string
          ui:field: EntityPicker
          ui:options:
            catalogFilter:
              kind: System

    - title: Infraštruktúra
      properties:
        database:
          title: Databáza
          type: string
          enum: [none, postgresql, mysql, mongodb]
          default: none
        cache:
          title: Cache
          type: string
          enum: [none, redis]
          default: none
        messageQueue:
          title: Message Queue
          type: string
          enum: [none, rabbitmq, kafka]
          default: none

  steps:
    - id: fetch
      name: Generovanie kódu
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          description: ${{ parameters.description }}
          owner: ${{ parameters.owner }}
          database: ${{ parameters.database }}

    - id: publish
      name: Vytvorenie repozitára
      action: publish:github
      input:
        allowedHosts: ['github.com']
        repoUrl: github.com?owner=myorg&repo=${{ parameters.name }}
        defaultBranch: main
        repoVisibility: internal

    - id: create-argocd-app
      name: ArgoCD Application
      action: argocd:create-application
      input:
        appName: ${{ parameters.name }}
        repoUrl: ${{ steps.publish.output.remoteUrl }}
        path: k8s/

    - id: register
      name: Registrácia v katalógu
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml

  output:
    links:
      - title: Repozitár
        url: ${{ steps.publish.output.remoteUrl }}
      - title: Otvoriť v katalógu
        entityRef: ${{ steps.register.output.entityRef }}

Čo šablóna vytvorí

Po kliknutí na "Create" sa automaticky:

  1. ✅ Vygeneruje repozitár so štandardnou štruktúrou
  2. ✅ Nakonfiguruje CI/CD pipeline (GitHub Actions)
  3. ✅ Vytvorí Kubernetes manifesty
  4. ✅ Zaregistruje ArgoCD Application
  5. ✅ Pridá službu do Software Catalog
  6. ✅ Vytvorí Grafana dashboard
  7. ✅ Nastaví alerting

Custom akcie pre Scaffolder

// plugins/scaffolder-actions/src/create-pagerduty.ts
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';

export const createPagerDutyService = createTemplateAction({
  id: 'pagerduty:create-service',
  description: 'Vytvorí PagerDuty service',
  schema: {
    input: {
      type: 'object',
      required: ['name', 'team'],
      properties: {
        name: { type: 'string' },
        team: { type: 'string' },
        escalationPolicy: { type: 'string' },
      },
    },
  },
  async handler(ctx) {
    const { name, team, escalationPolicy } = ctx.input;

    const response = await fetch('https://api.pagerduty.com/services', {
      method: 'POST',
      headers: {
        'Authorization': `Token token=${process.env.PAGERDUTY_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        service: {
          name,
          escalation_policy: { id: escalationPolicy, type: 'escalation_policy_reference' },
        },
      }),
    });

    const data = await response.json();
    ctx.output('serviceId', data.service.id);
    ctx.output('serviceUrl', data.service.html_url);
  },
});

Plugin ekosystém

Backstage má rozsiahly plugin ekosystém s 200+ pluginmi. Pluginy rozširujú portál o integrácie s externými nástrojmi.

Populárne pluginy

Plugin Funkcia
@backstage/plugin-kubernetes Zobrazenie podov, deploymentov, logov priamo v portáli
@backstage/plugin-techdocs Dokumentácia ako kód (MkDocs → portál)
@backstage/plugin-github-actions Stav CI/CD workflow
@roadiehq/backstage-plugin-argo-cd ArgoCD sync stav a história
@backstage/plugin-pagerduty On-call schedule a incidenty
@backstage/plugin-sonarqube Code quality metriky
@backstage/plugin-cost-insights Cloud cost monitoring
@backstage/plugin-jenkins Jenkins build stav

Kubernetes plugin

Kubernetes plugin zobrazuje live stav deploymentov pre každú službu:

# catalog-info.yaml — anotácie pre K8s plugin
metadata:
  annotations:
    backstage.io/kubernetes-id: order-service
    backstage.io/kubernetes-namespace: production
    backstage.io/kubernetes-label-selector: app=order-service

Vývojár vidí priamo v portáli:

  • Pody — stav, reštarty, resource usage
  • Deployments — repliky, rollout stav
  • Services — endpointy
  • HPA — autoscaling stav
  • Ingress — URL endpointy
  • Events — Kubernetes eventy

Vlastný plugin — príklad

// plugins/internal-tools/src/plugin.ts
import {
  createPlugin,
  createRoutableExtension,
} from '@backstage/core-plugin-api';

export const internalToolsPlugin = createPlugin({
  id: 'internal-tools',
  routes: {
    root: rootRouteRef,
  },
});

export const InternalToolsPage = internalToolsPlugin.provide(
  createRoutableExtension({
    name: 'InternalToolsPage',
    component: () =>
      import('./components/ToolsPage').then(m => m.ToolsPage),
    mountPoint: rootRouteRef,
  }),
);

TechDocs — dokumentácia ako kód

TechDocs umožňuje písať dokumentáciu v Markdowne priamo v repozitári a automaticky ju publikovať do portálu:

# mkdocs.yml v root repozitára
site_name: Order Service
nav:
  - Home: index.md
  - Architecture: architecture.md
  - API Reference: api.md
  - Runbook: runbook.md
  - ADRs:
    - ADR-001 Database Choice: adrs/001-database.md
    - ADR-002 Message Queue: adrs/002-message-queue.md

plugins:
  - techdocs-core

Alternatívy k Backstage

Backstage nie je jediná voľba. Existuje niekoľko komerčných aj open-source alternatív:

Porovnanie developer portálov

Vlastnosť Backstage Port Cortex OpsLevel Roadie
Typ Open-source SaaS SaaS SaaS Managed Backstage
Cena Zadarmo (self-hosted) Freemium Enterprise Enterprise Od $1500/mes
Service Catalog
Software Templates ✅ (Self-service)
Scorecards Community plugin ✅ (natívne) ✅ (core feature)
Dokumentácia TechDocs TechDocs
Customizácia Maximálna (kód) Vysoká (no-code) Stredná Stredná Vysoká
Údržba Vlastný tím Zero Zero Zero Minimálna
Plugin ekosystém 200+ Integrácie Integrácie Integrácie Backstage pluginy
Setup čas Týždne–mesiace Hodiny–dni Dni Dni Dni

Port

Port je SaaS developer portal s dôrazom na no-code konfiguráciu:

  • Software Catalog s flexibilným dátovým modelom
  • Self-service akcie definované cez UI (nie YAML)
  • Scorecards — meranie production readiness
  • Automations — pravidlá a triggery bez kódu
  • Silný v multi-cloud a Kubernetes prostrediach
// Port — príklad blueprint definície
{
  "identifier": "microservice",
  "title": "Microservice",
  "schema": {
    "properties": {
      "language": { "type": "string", "enum": ["Go", "Python", "Node.js"] },
      "on-call": { "type": "string" },
      "sla-tier": { "type": "string", "enum": ["tier-1", "tier-2", "tier-3"] },
      "last-deploy": { "type": "string", "format": "date-time" }
    }
  },
  "relations": {
    "team": { "target": "team", "required": true },
    "depends-on": { "target": "microservice", "many": true }
  }
}

Cortex

Cortex sa zameriava na service maturity a scorecards:

  • Scorecards — definovanie štandardov a meranie compliance
  • CQL (Cortex Query Language) — dotazovanie na služby
  • Initiatives — trackovanie systémových zmien naprieč tímami
  • Integrácie — 50+ integrácie s DevOps nástrojmi
  • Silný pre organizácie, ktoré chcú merateľné štandardy

OpsLevel

OpsLevel kombinuje service catalog s maturity rubrics:

  • Service Maturity — definovanie levelov (Bronze, Silver, Gold)
  • Checks — automatické overovanie štandardov
  • Self-service akcie — Terraform, Kubernetes provisioning
  • Tech Radar — prehľad technológií v organizácii

Roadie — Managed Backstage

Roadie poskytuje Backstage ako managed službu:

  • Žiadna údržba infraštruktúry
  • Predkonfigurované pluginy
  • SLA a support
  • Vhodný pre tímy, ktoré chcú Backstage bez operational overhead

Kedy čo použiť?

Scenár Odporúčanie
Veľká organizácia, silný platform tím Backstage (maximálna flexibilita)
Rýchly štart, no-code prístup Port (najrýchlejší time-to-value)
Dôraz na service maturity a compliance Cortex alebo OpsLevel
Chceme Backstage bez údržby Roadie
Malý tím, jednoduchý catalog Port (free tier)

Best Practices

1. Adoption stratégia

Developer portál je produkt — potrebuje product management prístup:

Fáza 1: Foundation (1-2 mesiace)
├── Nasadiť Backstage/Port
├── Importovať existujúce služby do katalogu
├── Integrovať s GitHub/GitLab
└── Onboardnúť 1-2 early adopter tímy

Fáza 2: Value (3-4 mesiace)
├── Software Templates pre top 3 use cases
├── TechDocs integrácia
├── Kubernetes plugin
└── Rozšíriť na 50 % tímov

Fáza 3: Scale (5-6 mesiacov)
├── Scorecards a maturity model
├── Self-service infraštruktúra
├── Vlastné pluginy pre interné nástroje
└── 100 % adoption

Fáza 4: Optimize (ongoing)
├── Developer satisfaction meranie
├── Automatizácia onboardingu
├── Advanced integrácie
└── Continuous improvement

2. Governance — catalog ako zdroj pravdy

# Pravidlá pre catalog-info.yaml:
# ✅ Povinné polia
metadata:
  name: required        # Unikátny identifikátor
  description: required # Čo služba robí
  annotations:
    pagerduty.com/service-id: required  # Kto je on-call?
spec:
  owner: required       # Kto vlastní službu?
  lifecycle: required   # production | experimental | deprecated
  system: required      # Do akého systému patrí?

Automatická validácia cez CI/CD:

# .github/workflows/catalog-validation.yml
name: Validate catalog-info.yaml
on:
  pull_request:
    paths: ['catalog-info.yaml']

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Validate entity
        run: |
          npx @backstage/catalog-model validate catalog-info.yaml
      - name: Check required fields
        run: |
          python scripts/check-catalog-fields.py catalog-info.yaml

3. InnerSource a community

Developer portál by mal podporovať InnerSource — interný open-source model:

  • Plugin contributions — tímy môžu prispievať vlastnými pluginmi
  • Template contributions — tímy zdieľajú svoje šablóny
  • Documentation culture — TechDocs ako štandard
  • Feedback kanál — Slack channel, office hours, surveys

4. Meranie úspechu

Metrika Ako merať Cieľ
Catalog coverage % služieb v katalógu 100 %
Template usage Nové projekty cez templates vs. manuálne > 80 %
Time to first deploy Od onboarding po prvý deployment < 1 deň
Developer satisfaction Quarterly survey (NPS) > 8/10
Search queries Počet vyhľadávaní za mesiac Rastúci trend
Self-service ratio % operácií bez ticketov > 90 %

5. Časté chyby

Chyba Dôsledok Riešenie
Mandátna adopcia bez hodnoty Odpor vývojárov Najprv ukáž hodnotu, potom rozširuj
Prázdny katalóg Nikto portál nepoužíva Auto-discovery + import existujúcich služieb
Príliš veľa customizácie Neudržateľné Začni s core features, iteruj
Žiadny owner portálu Portál zastaráva Dedikovaný platform tím
Ignorovanie feedback-u Zlá developer experience Pravidelné user research

Produkčný deployment Backstage

Docker deployment

# Dockerfile
FROM node:22-alpine AS build
WORKDIR /app
COPY . .
RUN yarn install --frozen-lockfile
RUN yarn tsc
RUN yarn build:backend

FROM node:22-alpine
WORKDIR /app
COPY --from=build /app/packages/backend/dist ./
COPY --from=build /app/app-config.yaml ./
RUN yarn install --production

ENV NODE_ENV=production
EXPOSE 7007
CMD ["node", "packages/backend", "--config", "app-config.yaml"]

Kubernetes deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backstage
  namespace: backstage
spec:
  replicas: 2
  selector:
    matchLabels:
      app: backstage
  template:
    metadata:
      labels:
        app: backstage
    spec:
      containers:
        - name: backstage
          image: myregistry/backstage:latest
          ports:
            - containerPort: 7007
          env:
            - name: POSTGRES_HOST
              valueFrom:
                secretKeyRef:
                  name: backstage-db
                  key: host
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: backstage-db
                  key: password
          resources:
            requests:
              memory: "512Mi"
              cpu: "250m"
            limits:
              memory: "1Gi"
              cpu: "1000m"
          readinessProbe:
            httpGet:
              path: /healthcheck
              port: 7007
            initialDelaySeconds: 30
            periodSeconds: 10

Internal Developer Portals transformujú spôsob, akým vývojári interagujú s infraštruktúrou a nástrojmi. Či už zvolíte Backstage pre maximálnu flexibilitu, Port pre rýchly štart, alebo Cortex pre service maturity — kľúčom je začať malým, iterovať na základe feedback-u a budovať kultúru, kde je portál prirodzeným štartovacím bodom každého vývojára.