dbt Docs gives you an auto generated site for your dbt project. It shows models, tests, columns, sources, and a lineage graph. It is built from the manifest and catalog artifacts that dbt produces. Teams use it to understand how data moves and what each model does.
The dbt Docs Backstage plugin brings that experience into your internal portal. It adds a dbt page to your entity views so engineers can browse models and tests in place. You can read the model documentation and inspect stats and columns. You can follow dependencies across nodes. You can open raw code and compiled code. This centralizes your data model context inside Backstage next to ownership and other system metadata. The plugin is listed in the Backstage plugin directory and focuses on viewing dbt models and tests documentation inside Backstage.
Common use cases are straightforward. Put data context next to service owners and runbooks. Speed debugging when a downstream model breaks. Give reviewers a quick way to see lineage and intent during changes. Reduce tab switching for data engineers and app teams. If you run a self hosted Backstage, this plugin fits that workflow and keeps data docs where people already work.
Installation Instructions
These instructions apply to self-hosted Backstage only.
Install the packages
From your Backstage root directory.
yarn --cwd packages/app add @iiben_orgii/backstage-plugin-dbt
yarn --cwd packages/backend add @iiben_orgii/backstage-plugin-dbt-backend
Add the dbt tab in the frontend
Edit packages/app/src/components/catalog/EntityPage.tsx.
Import the page and the availability helper.
// packages/app/src/components/catalog/EntityPage.tsx
import { DbtPage, isDBTAvailable } from "@iiben_orgii/backstage-plugin-dbt";
Add the tab in the service entity layout.
// Inside your serviceEntityPage definition
const serviceEntityPage = (
<EntityLayout>
<EntityLayout.Route if={isDBTAvailable} path="/dbt" title="dbt">
<DbtPage />
</EntityLayout.Route>
</EntityLayout>
);
Wire the backend for the new backend system
Edit packages/backend/src/index.ts.
Import the backend plugin.
// packages/backend/src/index.ts
import { dbtPlugin } from "@iiben_orgii/backstage-plugin-dbt-backend";
Add the plugin to your backend instance.
// Still in packages/backend/src/index.ts
const backend = createBackend();
backend.add(dbtPlugin);
backend.start();
Wire the backend for the legacy backend system
Create the router file.
Create packages/backend/src/plugins/dbt.ts.
// packages/backend/src/plugins/dbt.ts
import { createRouter } from "@iiben_orgii/backstage-plugin-dbt-backend";
import { Router } from "express";
import { PluginEnvironment } from "../types";
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({
logger: env.logger,
config: env.config,
});
}
Register the route in the backend index.
Edit packages/backend/src/index.ts.
// packages/backend/src/index.ts
import dbt from "./plugins/dbt";
async function main() {
// ...
const dbtEnv = useHotMemoize(module, () => createEnv("dbt"));
// ...
apiRouter.use("/dbt", await dbt(dbtEnv));
// ...
}
Add the app config schema to the app package
Create packages/app/config.d.ts.
export interface Config {
dbtdoc: {
/**
* Frontend root URL
* @visibility frontend
*/
bucket?: string;
backend?: "GoogleStorage" | "S3";
};
}
Update packages/app/package.json.
{
"files": [
"dist",
"config.d.ts"
],
"configSchema": "config.d.ts"
}
Set up a single shared bucket
Add this to app-config.yaml.
dbtdoc:
bucket: your-bucket-123
backend: GoogleStorage # or S3
Set up one bucket per service or override the path
Limitation. All dbt docs must use the same backend type. GoogleStorage or S3.
Add annotations in each entity catalog file. Example catalog-info.yaml.
apiVersion: backstage.io/v1alpha1
kind: Component
spec:
type: service
owner: user:guest
lifecycle: experimental
metadata:
name: test
annotations:
dbtdoc-bucket: my-bucket
dbtdoc-path: optional/override/path # Optional
Then set the backend type in app-config.yaml.
dbtdoc:
backend: GoogleStorage # or S3
Place your dbt docs in the bucket
Default layout for multi or single setup.
- {dbtdoc-bucket}/{kind}/{name}/manifest.json
- {dbtdoc-bucket}/{kind}/{name}/catalog.json
You can override the kind and name part with the dbtdoc-path annotation.
As of version two point two point zero you can place manifest.json and catalog.json at the bucket root level too.
GCS authentication
The backend uses Application Default Credentials for Google Cloud Storage. See ADC docs.
Summary of what you added
- Frontend tab in EntityPage that imports DbtPage and isDBTAvailable
- Backend plugin wired by dbtPlugin for the new backend system
- Or a router at packages/backend/src/plugins/dbt.ts plus a route in backend index for the legacy system
- Config schema in packages/app to expose dbtdoc settings
- app-config.yaml with bucket and backend
- Optional annotations dbtdoc-bucket and dbtdoc-path in your entities
Changelog
The dbt Docs plugin has not seen any significant changes since 6 months ago.
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.