Skip to main content

Backstage — Internal Developer Portal

Backstage is Spotify's open-source internal developer platform. It gives every developer in your team a single place to discover services, browse APIs, read runbooks, trigger pipelines, and check deployment status — all without needing to know where everything lives.


What It Solves

Without Backstage:
"Where is the API docs for the auth service?"
"Which team owns the payments service?"
"How do I deploy a new microservice?"
"Where is the Grafana dashboard for service X?"

With Backstage:
→ One portal. Everything catalogued. Self-service.

Key Features

FeatureWhat It Does
Software CatalogBrowse all services, APIs, libraries with owner + docs
TechDocsAuto-generated documentation from Markdown in repos
Software Templates"Create a new microservice" button — scaffolds repo, CI, k8s manifest
Kubernetes PluginSee pod status, logs, rollouts per service
ArgoCD PluginSee GitOps sync status per service
Grafana PluginEmbed dashboards per service
SearchSearch across services, docs, APIs

Architecture on Your Cluster

Developer Browser


Backstage Pod (k3s)
├── Frontend (React)
├── Backend (Node.js)
└── PostgreSQL (catalog data)

├── Reads from: GitLab repos (catalog-info.yaml)
├── Connects to: k8s API (pod status)
├── Connects to: ArgoCD API
└── Connects to: Grafana API

Deploy Backstage

Prerequisites

# Install Node.js 18+ on your local machine
node --version # v18+
npx @backstage/create-app@latest
# → name: minicloud-portal

Build Docker image

cd minicloud-portal
yarn install
yarn tsc
yarn build:backend

docker build -t backstage:latest \
-f packages/backend/Dockerfile .

Push to your Harbor registry (after Harbor is set up)

docker tag backstage:latest harbor.yourdomain.com/platform/backstage:latest
docker push harbor.yourdomain.com/platform/backstage:latest

Deploy to k3s

apiVersion: apps/v1
kind: Deployment
metadata:
name: backstage
namespace: platform
spec:
replicas: 1
selector:
matchLabels:
app: backstage
template:
metadata:
labels:
app: backstage
spec:
containers:
- name: backstage
image: harbor.yourdomain.com/platform/backstage:latest
ports:
- containerPort: 7007
env:
- name: POSTGRES_HOST
value: postgres-svc
- name: POSTGRES_PORT
value: "5432"
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: backstage-secrets
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: backstage-secrets
key: POSTGRES_PASSWORD
---
apiVersion: v1
kind: Service
metadata:
name: backstage
namespace: platform
spec:
type: LoadBalancer
selector:
app: backstage
ports:
- port: 80
targetPort: 7007

Register Your First Service

In each repo, add catalog-info.yaml:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-api
description: The main API service
tags:
- nodejs
- api
links:
- url: https://grafana.yourdomain.com/d/xxx
title: Grafana Dashboard
- url: https://argocd.yourdomain.com/applications/my-api
title: ArgoCD
spec:
type: service
lifecycle: production
owner: platform-team
providesApis:
- my-api-definition

Backstage auto-discovers this file and catalogs the service.


Software Templates (Golden Paths)

Create a "New Microservice" button that:

1. Developer fills form: name, language, team
2. Backstage scaffolds:
├── Git repo with code template
├── CI/CD pipeline config
├── Kubernetes manifests
├── Dockerfile
└── catalog-info.yaml
3. Repo created → pipeline triggers → ArgoCD deploys

This is the "golden path" — one click to a fully deployed service.


Done When

✔ Backstage pod Running
✔ Accessible via browser (MetalLB IP or Cloudflare tunnel)
✔ Services from GitLab repos appearing in catalog
✔ Kubernetes plugin showing pod status