Exploring Backstage — A Quick Start Guide
Frankly, although I had read related documentation before, I had never actually tried running Backstage myself. I always had the impression that Backstage was more of a developer portal than a developer platform. After sharing my understanding of platform engineering last week, someone in my circle suggested that I write an article about getting started with Backstage. This piqued my curiosity, and I decided to delve deeper into what Backstage really is.
Introduction to Backstage
Backstage is an open platform for building developer portals, unifying all infrastructure tools, services, and documentation to create a streamlined end-to-end development environment, open-sourced and donated to CNCF by Spotify. Backstage offers several core functionalities out of the box:
Software Catalog
The Software Catalog is a centralized system for tracking ownership and metadata of all software (services, websites, libraries, data pipelines, etc.) in the ecosystem. Developers provide the entity information of the software, and Backstage establishes links with existing entities based on this information, ultimately generating and saving the final version of the software entity in the catalog.
Various types of entity definitions can be found in the software catalog examples from the Backstage repository here.
Software Templates
Software Templates are tools that help developers create components in Backstage. By default, they can load code skeletons with templates containing variables and then deploy the templates to locations such as GitHub or GitLab.
TechDocs
TechDocs is Spotify’s in-house built documentation code solution directly integrated into Backstage. Developers write documentation in Markdown files coexisting with the code — with minimal configuration, a beautiful documentation site is available in Backstage.
Plugin Support
Plugin Support makes Backstage a single-page application composed of a collection of plugins, allowing developers to expose almost any type of infrastructure or software development tool as a feature in Backstage.
The plugin feature is arguably the biggest highlight of Backstage, greatly enhancing its customizability through the plugin ecosystem, currently featuring 5 core plugins and nearly 200 third-party plugins.
Running Backstage can be done locally or through containerized deployment.
Running Locally
To run Backstage locally, NodeJS 18, yarn 1.22, and npx environments are required. Here are the steps to start Backstage:
Creating a Backstage App
Execute the following command and enter the application name as prompted to create a Backstage app. You can also use the one I created.
npx @backstage/create-app@latest
By default, local operation uses better-sqlite3
as storage for the software catalog. Execute the following command before starting:
npm rebuild better-sqlite3
Starting Backstage
Then, execute yarn dev
to start Backstage, and open http://localhost:3000
in a browser to access Backstage.
Of course, Backstage also supports databases for persistence, such as PostgreSQL. In app-config.yaml
, configure the database as follows:
backend:
database:
# client: better-sqlite3
# connection: ':memory:'
client: pg
connection:
host: ${POSTGRES_SERVICE_HOST}
port: ${POSTGRES_SERVICE_PORT}
user: ${POSTGRES_USER}
password: ${POSTGRES_PASSWORD}
After modifying the configuration, add environment variables and re-execute the command.
export POSTGRES_SERVICE_HOST=127.0.0.1
export POSTGRES_SERVICE_PORT=5432
export POSTGRES_USER= backstage
export POSTGRES_PASSWORD=backstage
yarn dev
Adding Software Entities
In an existing Java project, I added catalog-info.yaml
and included software entity information.
On the software catalog page, click CREATE
and REGISTER EXISTING COMPONENT
in sequence, fill in the address of the catalog-info.yaml
(https://github.com/addozhang/tekton-demo/blob/main/catalog-info.yaml
) in the form, and then click ANALYZE
and IMPORT
.
Now, you can see the imported entity information and the component relationships created based on that information.
In addition to displaying information about the software, we hope to build the project. I pre-added a GitHub workflow for it; let’s see how to build on Backstage.
Configuring CI/CD
At this point, if you open the CI/CD card, you can see a popup requesting authorization for Backstage to access the GitHub repository. Due to configuring the authentication provider, the following error will appear.
Create an application in the GitHub Developer Settings with the following information:
- Application Name: Backstage (or another name)
- Homepage URL:
http://localhost:3000
- Authorization callback URL:
http://localhost:7007/api/auth/github/handler/frame
After successful creation, CLIENT_ID
and CLIENT_SECRET
can be obtained.
Modify the Backstage configuration file app-config.yaml
, adding:
auth:
environment: development
providers:
github:
development:
clientId: ${AUTH_GITHUB_CLIENT_ID}
clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}
Where
export POSTGRES_SERVICE_HOST=127.0.0.1
export POSTGRES_SERVICE_PORT=5432
export POSTGRES_USER= backstage
export POSTGRES_PASSWORD=backstage
export AUTH_GITHUB_CLIENT_ID=<CLIENT_ID>
export AUTH_GITHUB_CLIENT_SECRET=<CLIENT_SECRET>
yarn dev
Running on Kubernetes
Firstly, you need a K8s cluster. On Kubernetes, we are using PostgreSQL as persistent storage for this instance.
kubectl create namespace backstage
Deploying PostgreSQL
Create a Secret for configuring PostgreSQL authentication information.
kubectl apply -n backstage -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: postgres-secrets
type: Opaque
data:
POSTGRES_USER: YmFja3N0YWdl
POSTGRES_PASSWORD: YmFja3N0YWdl
EOF
Use local disks to create PVC and PVC.
kubectl apply -n backstage -f - <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-storage
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 2G
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: '/mnt/data'
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-storage-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2G
EOF
Deploying PostgreSQL.
kubectl apply -n backstage -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: backstage
spec:
replicas: 1
selector:
matchLabels:
app: backstage
template:
metadata:
labels:
app: backstage
spec:
containers:
- name: backstage
image: addozhang/backstage
imagePullPolicy: Always
ports:
- name: http
containerPort: 7007
envFrom:
- secretRef:
name: postgres-secrets
- secretRef:
name: github-oauth-secrets
---
apiVersion: v1
kind: Service
metadata:
name: backstage
spec:
selector:
app: backstage
ports:
- name: http
port: 80
targetPort: http
EOF
Configuring GitHub OAuth Authentication Information
kubectl apply -n backstage -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: github-oauth-secrets
type: Opaque
data:
AUTH_GITHUB_CLIENT_ID: <CLIENT_ID base64>
AUTH_GITHUB_CLIENT_SECRET: <CLIENT_SECRET base64>
EOF
Deploying Backstage
kubectl apply -n backstage -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: backstage
spec:
replicas: 1
selector:
matchLabels:
app: backstage
template:
metadata:
labels:
app: backstage
spec:
volumes:
- name: config-volume
configMap:
name: bs-app-config
items:
- key: "app-config.production.yaml"
path: "app-config.production.yaml"
containers:
- name: backstage
image: addozhang/backstage:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 7007
envFrom:
- secretRef:
name: github-oauth-secrets
- secretRef:
name: postgres-secrets
---
apiVersion: v1
kind: Service
metadata:
name: backstage
spec:
selector:
app: backstage
ports:
- name: http
port: 80
targetPort: http
EOF
Access the Backstage page http://localhost:7077
.
kubectl port-forward --namespace=backstage svc/backstage 7007:80
Conclusion
Through this article, we’ve learned about the basic concepts of Backstage and how to run it in different environments.
I believe that Backstage is more aptly defined as a developer portal rather than a comprehensive developer platform. It essentially is a flexible framework, not an out-of-the-box comprehensive solution. To fully utilize its potential, platform teams need to understand developers’ needs deeply and customize Backstage by introducing or developing specialized plugins, thus achieving true self-service capabilities.
Moreover, Backstage does not mean to replace DevOps. In fact, DevOps is more of a cultural and practice concept rather than a specific tool. The framework-plus-plugins approach of Backstage actually aims to address specific challenges encountered in DevOps practices, especially in its implementation phase.
In summary, Backstage provides developers with a powerful and flexible toolkit, integrating a variety of functions and services to help teams better implement the DevOps philosophy, enhancing development efficiency and project management efficacy.