Octopus Deploy is a continuous delivery platform that automates releases and runbooks across your environments. It picks up after your build, orchestrates promotions, and provides guardrails like approvals and audit. It targets Kubernetes, virtual machines, and major clouds. You can deploy anywhere Octopus can reach.
The Octopus Deploy Backstage plugin brings this release context into your service catalog. On each service page you can see recent releases from its Octopus project and the current status for those releases. You get quick links back to Octopus for deeper detail. The plugin also offers Scaffolder field extensions so templates can prompt engineers to choose Octopus resources during creation. That helps teams standardize how new services connect to Octopus.
If your organization already uses Backstage for discovery and Octopus for deployments, the plugin reduces context switching. Engineers can answer simple questions from the catalog. What shipped. Where it is now. What failed. Platform teams get a clearer picture without tab hopping.Note.
Installation Instructions
These instructions apply to self-hosted Backstage only.
Install the frontend package
Run this from your Backstage root
yarn --cwd packages/app add @backstage-community/plugin-octopus-deploy
Configure the Backstage proxy
Set an API key in your Octopus Deploy account. Put the key in an environment variable named OCTOPUS_API_KEY.
Example for the backend process
# From packages/backend
echo "OCTOPUS_API_KEY=YOUR_KEY_HERE" >> .env
Add a proxy endpoint in your app config. Replace the server URL with your own
# app-config.yaml
proxy:
endpoints:
'/octopus-deploy':
target: 'https://your-octopus-server.example.com/api'
headers:
X-Octopus-ApiKey: ${OCTOPUS_API_KEY}
Optional link to the Octopus web UI
# app-config.yaml
octopusdeploy:
webBaseUrl: "https://your-octopus-server.example.com"
Legacy backend setup
If your legacy backend already has the proxy plugin, you can skip this part.
Install the proxy backend package
yarn --cwd packages/backend add @backstage/plugin-proxy-backend
Create the proxy plugin file if it is missing
// packages/backend/src/plugins/proxy.ts
import { createRouter } from '@backstage/plugin-proxy-backend';
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
export default async function createPlugin(env: PluginEnvironment): Promise<Router> {
return await createRouter({
logger: env.logger,
config: env.config,
discovery: env.discovery,
tokenManager: env.tokenManager,
});
}
Wire it up in the legacy backend index
// packages/backend/src/index.ts
import proxy from './plugins/proxy';
// inside the main bootstrap function
const proxyEnv = useHotMemoize(module, () => createEnv('proxy'));
app.use('/proxy', await proxy(proxyEnv));
New backend setup
If you use the new backend system, add the proxy plugin to the backend builder
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
// other plugins
backend.add(import('@backstage/plugin-app-backend'));
// proxy plugin
backend.add(import('@backstage/plugin-proxy-backend'));
backend.start();
Show Octopus releases on the entity page
Add the component to your catalog entity page
// packages/app/src/components/catalog/EntityPage.tsx
import React from 'react';
import { EntitySwitch } from '@backstage/plugin-catalog';
import {
isOctopusDeployAvailable,
EntityOctopusDeployContent,
} from '@backstage-community/plugin-octopus-deploy';
export const cicdContent = (
<EntitySwitch>
{/* other components */}
<EntitySwitch.Case if={isOctopusDeployAvailable}>
<EntityOctopusDeployContent defaultLimit={25} />
</EntitySwitch.Case>
</EntitySwitch>
);
Add catalog annotations
Add the project annotation to your entity in the catalog. The value is the project ID from Octopus Deploy
# catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-service
annotations:
octopus.com/project-id: Projects-102
spec:
type: service
If the project lives in a non default space, prefix with the space ID
# catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-service
annotations:
octopus.com/project-id: Spaces-2/Projects-102
spec:
type: service
Add the Scaffolder field extension
Register the extension in your app so it shows on the create page
// packages/app/src/App.tsx
import React from 'react';
import { FlatRoutes } from '@backstage/core-app-api';
import { Route } from 'react-router';
import { ScaffolderPage, ScaffolderFieldExtensions } from '@backstage/plugin-scaffolder';
import { OctopusDeployDropdownFieldExtension } from '@backstage-community/plugin-octopus-deploy';
const routes = (
<FlatRoutes>
{/* other routes */}
<Route path="/create" element={<ScaffolderPage />}>
<ScaffolderFieldExtensions>
<OctopusDeployDropdownFieldExtension />
</ScaffolderFieldExtensions>
</Route>
</FlatRoutes>
);
export default routes;
Use the field in a template
# template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: my-template
spec:
owner: team-a
type: service
parameters:
- title: Octopus Project Group
properties:
projectName:
title: Octopus Project Group
type: string
ui:field: OctopusDeployProjectGroupDropdown
steps: []
Changelog
This changelog is produced from commits made to the Octopus Deploy plugin since a year ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.
Features
- Add external links to Octopus release version details in the deployments table #2961 7 months ago
- Show the Octopus project link in the table title #2961 7 months ago
Bug Fixes
- Fix search for states in the deployments table #2961 7 months ago
- Fix state icon alignment next to the state #2961 7 months ago
Maintenance
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.