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:
- ✅ Vygeneruje repozitár so štandardnou štruktúrou
- ✅ Nakonfiguruje CI/CD pipeline (GitHub Actions)
- ✅ Vytvorí Kubernetes manifesty
- ✅ Zaregistruje ArgoCD Application
- ✅ Pridá službu do Software Catalog
- ✅ Vytvorí Grafana dashboard
- ✅ 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.