Skip to main content
Version: v3

Composing a Portal

A DevPortal installation is a service catalog and a way to create projects from templates. Teams register services, create new ones from templates, and browse the software landscape. Plugin composition lets developers see pod status, trigger deployments, check code quality, and browse dashboards from service pages. A 3.x portal combines four parts: the image with the core, the chart, the catalog index image behind the default plugins and Marketplace, and the configuration fragments.

The four parts of a 3.x portal​

  • The image ships the Backstage core with its static backend plugins (authentication, catalog, scaffolder, search, permissions) and the names of the default plugins, in /opt/app-root/src/factory-plugins.yaml. See Dynamic Plugins.
  • The chart (devportal) includes the catalog index's default plugin file (dynamic-plugins.default.yaml) through global.dynamic.includes, adds operator plugins through the global.dynamic.plugins list, and carries operator configuration through upstream.backstage.appConfig and ordered extraAppConfig fragments. See Configuration Hierarchy.
  • The catalog index image supplies the default plugins with their configuration, and the installable plugins shown in the Marketplace UI. Marketplace selections are stored in PostgreSQL and applied when the portal restarts with the installer.
  • The configuration fragments set branding, authentication, catalog locations, and per-plugin backend settings. On the local stack you add a fragment as described in Add a configuration fragment.

Three levels of composition​

Every plugin activates across three layers. All three must be in place before a developer sees live data.

1. Load — the default plugins, chart values, the operator file, or Marketplace​

This controls which plugins are present at all. A plugin is loaded if any selection source includes it: the default plugins from the catalog index (dynamic-plugins.default.yaml), a global.dynamic.plugins entry on Kubernetes, an operator plugin file entry on the local stack, or a Marketplace install. Enabling a plugin loads its code: UI components and backend routes become available. But nothing appears to the developer yet.

Some plugins need configuration values in a fragment before the portal starts. If the portal stops after a plugin change, read the backend logs and add the required settings first.

2. Context — entity annotations​

Plugins are context-aware by design. They do not add global tabs. They add tabs and cards to specific catalog entities, and only when those entities carry the right annotation.

# catalog-info.yaml
metadata:
annotations:
backstage.io/kubernetes-label-selector: 'app=my-service'

Without this annotation on the entity, the plugin is loaded but idle. With it, the matching tab appears on that entity only. A platform with dozens of services does not need every plugin visible on every entity: each service declares what it uses, and the portal shows only the plugins that belong to that service.

3. Backend — configuration fragments​

The tab appears, but it needs to know where to fetch data from. The backend configuration provides that: cluster URLs and tokens, base URLs and API keys for each integration. Without it, the tab loads and shows an error or empty state. With all three layers in place, the tab displays live data.

The diagnostic model​

A plugin that fails to show data has failed at one of these three levels. Diagnose in layer order: load before context before backend, because each layer assumes the previous one succeeded.

SymptomLayerFix
Portal does not boot, or plugin absent on every entityLoad — install failed or plugin not enabledRead the installer logs for install and skip lines; confirm the entry and its reference
Tab not visible on a specific entityContext — annotation missingAdd the annotation to that entity's catalog-info.yaml
Tab visible, empty or errorBackend — configuration missing or unreachableCheck the fragments for the relevant integration, then credentials and reachability

The Day-0 to Day-2 progression​

This is a deliberate sequence, not a checklist you complete once.

Day-0: Foundation​

Catalog populated: services, APIs, and resources registered through catalog locations. Authentication configured through the auth fragment. Guest sign-in signs everyone in as the admin user and is for evaluation only. Chart 1.0.3 and earlier turn it on; from chart 1.0.4 the chart turns it off.

Day-1: Connecting services to their tooling​

Enable plugins through chart values, the operator file, or Marketplace. Add annotations to catalog entities: each annotation is a claim that an entity owns a workload, a project, or a dashboard. Configure backends in the fragments.

Day-2: The operational hub​

Developers operate services without leaving the portal: CI tabs show pipeline status alongside the service entity, Kubernetes tabs show pod health, and code quality tabs show analysis results.

The 2.x environment and cluster journey relied on VeeCode plugins that 3.x does not ship, neither as default plugins nor in the Marketplace.

References​