Backstage is an open platform for building developer portals. Originally built at Spotify, it unifies all your infrastructure, services, documentation, and tools into a single, consistent interface.
What Is Backstage?
Backstage is a CNCF incubating project that provides a framework for building developer portals. It includes a software catalog, TechDocs, templates for scaffolding new projects, and a plugin architecture with 100+ community plugins.
Key Features:
- Software Catalog (all services in one place)
- TechDocs (docs-as-code)
- Software Templates (scaffold new projects)
- Kubernetes integration
- CI/CD visibility
- API documentation
- Search across all resources
- 100+ plugins
Quick Start
# Create a new Backstage app
npx @backstage/create-app@latest
cd my-backstage-app
# Start development server
yarn dev
# Catalog at http://localhost:3000
# API at http://localhost:7007
Software Catalog
# catalog-info.yaml (add to any repo)
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: order-service
description: Handles order processing and payments
annotations:
github.com/project-slug: myorg/order-service
backstage.io/techdocs-ref: dir:.
tags:
- python
- grpc
links:
- url: https://grafana.example.com/d/orders
title: Grafana Dashboard
spec:
type: service
lifecycle: production
owner: team-backend
system: e-commerce
dependsOn:
- component:payment-gateway
- resource:orders-db
providesApis:
- order-api
Backstage REST API
import requests
BACKSTAGE = "http://localhost:7007/api"
# Get all entities from catalog
entities = requests.get(f"{BACKSTAGE}/catalog/entities").json()
for entity in entities[:10]:
kind = entity["kind"]
name = entity["metadata"]["name"]
print(f"[{kind}] {name}")
# Search catalog
results = requests.get(f"{BACKSTAGE}/catalog/entities", params={
"filter": "kind=Component,spec.type=service"
}).json()
for svc in results:
owner = svc["spec"].get("owner", "unknown")
lifecycle = svc["spec"].get("lifecycle", "unknown")
print(f"Service: {svc['metadata']['name']}, Owner: {owner}, Lifecycle: {lifecycle}")
# Get specific entity
entity = requests.get(f"{BACKSTAGE}/catalog/entities/by-name/Component/default/order-service").json()
print(f"Name: {entity['metadata']['name']}")
print(f"Description: {entity['metadata'].get('description', '')}")
print(f"Owner: {entity['spec']['owner']}")
# Search
search_results = requests.get(f"{BACKSTAGE}/search/query", params={
"term": "order",
"types[0]": "software-catalog"
}).json()
for r in search_results["results"]:
print(f"Found: {r['document']['title']} ({r['document']['kind']})")
Software Templates
# template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: microservice-template
title: Create a Microservice
description: Scaffold a new microservice with CI/CD
spec:
owner: platform-team
type: service
parameters:
- title: Service Info
properties:
name:
title: Service Name
type: string
description:
title: Description
type: string
language:
title: Language
type: string
enum: [python, go, typescript]
steps:
- id: fetch
name: Fetch Template
action: fetch:template
input:
url: ./skeleton
values:
name: ${{ parameters.name }}
- id: publish
name: Publish to GitHub
action: publish:github
input:
repoUrl: github.com?owner=myorg&repo=${{ parameters.name }}
- id: register
name: Register in Catalog
action: catalog:register
input:
repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
catalogInfoPath: /catalog-info.yaml
Resources
- Backstage Docs
- Backstage GitHub — 28K+ stars
- Plugin Marketplace
Need to scrape web data for your developer portal? Check out my web scraping tools on Apify — production-ready actors for Reddit, Google Maps, and more. Questions? Email me at spinov001@gmail.com
Top comments (0)