This guide covers a variety of production persistence use cases which are supported out of the box by Backstage. The database manager allows the developer to set the client and database connection details on a per plugin basis in addition to the base client and connection configuration. This means that you can use a SQLite 3 in-memory database for a specific plugin whilst using PostgreSQL for everything else and so on.
By default, Backstage uses automatically created databases for each plugin whose
names follow the
backstage_plugin_<pluginId> pattern, e.g.
backstage_plugin_auth. You can configure a different database name prefix for
use cases where you have multiple deployments running on a shared database
instance or cluster.
With infrastructure defined as code or data (Terraform, AWS CloudFormation, etc.), you may have database credentials which lack permissions to create new databases or you do not have control over the database names. In these instances, you can set the database connection configuration on a per plugin basis.
Backstage supports all of these use cases with the
DatabaseManager provided by
@backstage/backend-common. We will now cover how to use and configure
Please ensure the appropriate database drivers are installed in your
package. If you intend to use both PostgreSQL and SQLite, you can install
both of them.
# From your Backstage root directory
# install pg if you need PostgreSQL
yarn add --cwd packages/backend pg
# install SQLite 3 if you intend to set it as the client
yarn add --cwd packages/backend better-sqlite3
From an operational perspective, you only need to install drivers for clients that are actively used.
You should set the base database client and connection information in your
app-config.yaml (or equivalent) file. The base client and configuration is
used as the default which is extended for each plugin with the same or unset
client type. If a client type is specified for a specific plugin which does not
match the base client, the configuration set for the plugin will be used as is
without extending the base configuration.
Client type and configuration for plugins need to be defined under
backend.database.plugin.<pluginId>. As an example,
catalog is the
pluginId for the catalog plugin and any configuration defined under that block
is specific to that plugin. We will now explore more detailed example
Minimal In-Memory Configuration
In the example below, we are using
better-sqlite3 in-memory databases for all
plugins. You may want to use this configuration for testing or other non-durable
The example below uses PostgreSQL (
pg) as the database client for all plugins.
auth plugin uses a user defined database name instead of the automatically
generated one which would have been
Custom Database Name Prefix
The configuration below uses
example_prefix_ as the database name prefix
backstage_plugin_. Plugins such as
catalog will use
Connection Configuration Per Plugin
catalog use connection configuration with different
credentials and database names. This type of configuration can be useful for
environments with infrastructure as code or data which may provide randomly
generated credentials and/or database names.
PostgreSQL and SQLite 3
The example below uses PostgreSQL (
pg) as the database client for all plugins
auth plugin which uses
better-sqlite3. As the
auth plugin's client
type is different from the base client type, the connection configuration for
auth is used verbatim without extending the base configuration for PostgreSQL.
Check Your Databases
DatabaseManager will attempt to create the databases if they do not exist.
If you have set credentials per plugin because the credentials in the base
configuration do not have permissions to create databases, you must ensure they
exist before starting the service. The service will not be able to create them,
it can only use them.
As Backstage attempts to check if the database exists, you may need to grant privileges to list or show databases for a given user. For PostgreSQL, you would grant the following:
GRANT SELECT ON pg_database TO some_user;
GRANT SHOW DATABASES ON *.* TO some_user;
The mechanisms in this guide should help you tackle different database deployment situations. Good luck!