Skip to main content
Version: v0.11.x

Backstage Configuration

OpenChoreo uses Backstage as its developer portal, providing a unified interface for managing organizations, projects, components, and deployments. This guide covers configuration options for customizing Backstage in your OpenChoreo deployment.

Backstage configuration is done via Helm values in the Control Plane chart.

Core Configuration​

Console/UI URL:

backstage:
appConfig:
app:
baseUrl: "https://console.example.com"
backend:
baseUrl: "https://console.example.com"

OpenChoreo API URL:

openchoreoApi:
ingress:
enabled: true
hosts:
- host: api.example.com
paths:
- path: /

Authentication​

By default, OpenChoreo configures Thunder as the identity provider for Backstage with a pre-configured OAuth client for testing purposes. If you want to integrate an external identity provider instead, create an OAuth 2.0 client with the following requirements:

OAuth Client Requirements:

  1. Grant Types: The OAuth client must support both:

    • authorization_code - For user authentication and login flows
    • client_credentials - For service-to-service authentication
  2. Token Format: Configure the client to issue JWT tokens (not opaque tokens)

  3. Redirect URLs: Add the Backstage callback URL:

    • <protocol>://<backstage-domain>/api/auth/openchoreo-auth/handler/frame
    • Replace <protocol> with http or https and <backstage-domain> with your actual Backstage domain

Helm Configuration:

Once you have created the OAuth client, configure Backstage with the client credentials:

helm upgrade --install openchoreo-control-plane oci://ghcr.io/openchoreo/helm-charts/openchoreo-control-plane \
--version 0.11.0 \
--namespace openchoreo-control-plane \
--reuse-values \
--set backstage.auth.clientId="your-client-id" \
--set backstage.auth.clientSecret="your-client-secret" \
--set backstage.auth.redirectUrls\[0\]="<protocol>://<backstage-domain>/api/auth/openchoreo-auth/handler/frame"

See Identity Provider Configuration for detailed setup instructions.

Feature Flags​

backstage:
features:
workflows:
enabled: true # Requires Build Plane
observability:
enabled: true # Requires Observability Plane

Resource Configuration​

backstage:
replicas: 1
resources:
limits:
cpu: 2000m
memory: 2Gi
requests:
cpu: 200m
memory: 256Mi

autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 5

Environment Variables​

Add custom environment variables to the Backstage deployment:

backstage:
env:
- name: NODE_ENV
value: production
- name: LOG_LEVEL
value: info
- name: PORT
value: "7007"

Commonly Used Variables​

VariableDescriptionDefault
NODE_ENVNode.js environmentproduction
LOG_LEVELLogging verbosityinfo
PORTHTTP server port7007
OPENCHOREO_API_URLOpenChoreo API endpointAuto-configured
THUNDER_BASE_URLThunder IdP URLAuto-configured

Ingress Configuration​

backstage:
ingress:
enabled: true
className: "your-ingress-class"
hosts:
- host: console.example.com
paths:
- path: /
tls:
- secretName: console-tls
hosts:
- console.example.com

Service Configuration​

backstage:
service:
type: ClusterIP
port: 7007

OpenChoreo API Integration​

Backstage communicates with the OpenChoreo API for backend operations:

backstage:
openchoreoApi:
url: "" # Auto-configured to internal service URL

The API URL defaults to http://{release-name}-api.{namespace}.svc.cluster.local:8080/api/v1.

Backend Secret​

For session encryption (should be stable across restarts):

backstage:
backendSecret: "your-32-character-secret-here"

Database Configuration​

Backstage requires a database to store catalog entities, user settings, and plugin data. OpenChoreo supports two database backends:

BackendUse CasePersistenceScalability
SQLite (default)Development, single-replicaOptional (emptyDir or PVC)Single replica only
PostgreSQLProduction, multi-replicaExternal databaseHorizontal scaling

Default Configuration (SQLite)​

By default, Backstage uses SQLite with an emptyDir volume, which means data is lost when the pod restarts:

backstage:
database:
type: sqlite
sqlite:
persistence:
enabled: false # Uses emptyDir (data lost on restart)

SQLite with Persistence​

For development environments where you want data to persist across restarts but don't need horizontal scaling:

backstage:
database:
type: sqlite
sqlite:
mountPath: /app/.config/backstage
persistence:
enabled: true
size: 1Gi
storageClassName: "" # Uses default storage class
accessMode: ReadWriteOnce
warning

SQLite locks the database file, preventing multiple Backstage replicas from running simultaneously. For high-availability deployments, use PostgreSQL.

PostgreSQL for Production​

For production deployments requiring high availability and data durability, configure an external PostgreSQL database.

Prerequisites​

  1. Provision a PostgreSQL Database: Use a managed service (AWS RDS, Google Cloud SQL, Azure Database for PostgreSQL) or a self-hosted PostgreSQL instance
  2. Create a Database: Create a database for Backstage (e.g., backstage)
  3. Create a Database User: Create a user with full access to the database

Backstage automatically creates per-plugin databases (e.g., backstage_plugin_catalog, backstage_plugin_auth) using the provided credentials.

Helm Configuration​

For managed PostgreSQL services or external databases:

helm upgrade --install openchoreo-control-plane oci://ghcr.io/openchoreo/helm-charts/openchoreo-control-plane \
--version 0.11.0 \
--namespace openchoreo-control-plane \
--reuse-values \
--set backstage.database.type=postgresql \
--set backstage.database.postgresql.host="postgres.example.com" \
--set backstage.database.postgresql.port=5432 \
--set backstage.database.postgresql.user="backstage" \
--set backstage.database.postgresql.password="your-secure-password" \
--set backstage.database.postgresql.database="backstage"

PostgreSQL Configuration Reference​

ParameterDescriptionDefault
backstage.database.typeDatabase backend (sqlite or postgresql)sqlite
backstage.database.postgresql.hostPostgreSQL server hostname""
backstage.database.postgresql.portPostgreSQL server port5432
backstage.database.postgresql.userDatabase usernamebackstage
backstage.database.postgresql.passwordDatabase password""
backstage.database.postgresql.databaseDatabase namebackstage

Verifying PostgreSQL Connection​

After deploying with PostgreSQL, verify the connection:

# Check Backstage pod is running
kubectl get pods -n openchoreo-control-plane -l app.kubernetes.io/component=backstage

# Verify database environment variables
kubectl exec -n openchoreo-control-plane deployment/openchoreo-ui -- env | grep -E "DATABASE|POSTGRES"

# Check logs for database connection errors
kubectl logs -n openchoreo-control-plane deployment/openchoreo-ui | head -50

If PostgreSQL is configured correctly, Backstage will create per-plugin databases automatically:

# List databases created by Backstage (run against your PostgreSQL instance)
psql -U backstage -d backstage -c "\l" | grep backstage_plugin

Expected output shows databases like backstage_plugin_catalog, backstage_plugin_auth, etc.

Health Checks​

Backstage health checks are pre-configured:

CheckEndpointDefault
Liveness/healthcheckEnabled
Readiness/healthcheckEnabled

Example Configurations​

backstage:
enabled: true
replicas: 1
baseUrl: "http://localhost:7007"
ingress:
enabled: true
hosts:
- host: localhost
paths:
- path: /
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 100m
memory: 256Mi
features:
workflows:
enabled: true
observability:
enabled: true

Troubleshooting​

Backstage Not Loading​

Check pod status and logs:

kubectl get pods -n openchoreo-control-plane -l app.kubernetes.io/name=backstage
kubectl logs -n openchoreo-control-plane deployment/backstage

Authentication Issues​

Verify OAuth configuration:

# Check Backstage environment variables
kubectl exec -n openchoreo-control-plane deployment/backstage -- env | grep -E "(AUTH|THUNDER)"

# Check Thunder is running
kubectl get pods -n openchoreo-control-plane -l app.kubernetes.io/name=thunder

API Connection Errors​

Verify OpenChoreo API is accessible:

# Check API pod
kubectl get pods -n openchoreo-control-plane -l app.kubernetes.io/name=openchoreo-api

# Test API from Backstage pod
kubectl exec -n openchoreo-control-plane deployment/backstage -- \
curl -s http://openchoreo-control-plane-api:8080/api/v1/health

Database Connection Issues​

If Backstage fails to start with database errors:

For SQLite errors:

# Check if the pod has write access to the database directory
kubectl exec -n openchoreo-control-plane deployment/openchoreo-ui -- ls -la /app/.config/backstage

# Check for SQLite-specific errors in logs
kubectl logs -n openchoreo-control-plane deployment/openchoreo-ui | grep -i "sqlite\|database"

For PostgreSQL errors:

# Verify PostgreSQL environment variables are set
kubectl exec -n openchoreo-control-plane deployment/openchoreo-ui -- env | grep POSTGRES

# Test PostgreSQL connectivity from the pod
kubectl exec -n openchoreo-control-plane deployment/openchoreo-ui -- \
nc -zv <postgres-host> 5432

# Check for connection errors in logs
kubectl logs -n openchoreo-control-plane deployment/openchoreo-ui | grep -i "postgres\|connection\|ECONNREFUSED"

Common issues:

ErrorCauseSolution
ECONNREFUSEDPostgreSQL not reachableVerify hostname, port, and network policies
password authentication failedInvalid credentialsCheck backstage.database.postgresql.password
database does not existMissing databaseCreate the database on PostgreSQL server
connection.filename is not supportedOutdated Backstage imageUpgrade to latest control plane chart

Next Steps​