A job I recently applied to requires a candidate with experience writing docs for Backstage, Spotify’s open-source platform for creating developer portals. Backstage’s core TechDocs plugin uses MkDocs for content and YAML for configuration. While I’m very comfortable with MkDocs and YAML, my only experience with Backstage was watching introductory YouTube videos after a former colleague suggested we could use it at Specialized.
Naturally, I was intrigued, particularly as Backstage uses a documentation tool (MkDocs) I already use daily. However, being made redundant at Specialized put the kibosh on that ever becoming a possibility.
So, with time on my hands and the pressures of finding a job providing motivation, I installed it on my MacBook Pro, aiming to play with its documentation features and learn how the platform works in general.
While the Backstage docs are good, they don’t include an end-to-end process for installing on macOS, so I decided to write one for future reference, and for anyone else who might find it helpful.
In summary, the steps are:
- Install Homebrew
- Install NodeJS with Homebrew
- Install Postgres with Homebrew
- Install Backstage with npx
- Config Backstage to use Postgres
Homebrew Link to heading
Homebrew is a utility for installing open-source utilities and libraries on macOS, analogous to the package managers you find in Linux distros, such as apt and pacman. It should be the first thing anyone ever considering developing on a Mac should install!
You can find installation instructions on the Homebrew homepage, but in summary, open Terminal.app (in Applications/Utilities) and enter the following command:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
You may be prompted to enter your macOS admin password as part of the installation process. You may also have to install Apple’s command line developer tools for Xcode — allow this to proceed if prompted.
A great feature of Homebrew is that it installs packages to /usr/local
and keeps them separated from the packages installed in macOS by default by Apple, and are usually outdated.
Node Link to heading
Backstage.io is NodeJS app, so we’ll need a compatible Node version once Homebrew is successfully installed. At the time of writing, Backstage requires Node version 17, but I prefer to stick with Long-Term Support versions, so I installed Node 18.
To install Node 18 using Homebrew, enter the following command into your Terminal and press return.
$ brew install node@18
Once you install Node, create a symlink in your zshrc file to point to the Node executable.
$ echo 'export PATH="/usr/local/opt/node@18/bin:$PATH"' >> ~/.zshrc
Next, refresh your terminal session to use your updated zshrc file.
$ source ~/.zshrc
Test it’s working by querying your node installation’s version.
$ node -v
If you see a version number displayed, for example, v18.13.0
, you are ready to install Backstage and its dependencies.
Postgres Link to heading
By default, Backstage uses an in-memory database (SQLite) for temporary storage, and the database is erased each time Backstage tops. To persist data between sessions, you’ll need to use Postgres.
If you don’t already have Postgres installed, you can do so using Homebrew.
$ brew install postgres@15
As with Node, we must reference our Postgres installation in our zshrc file, as follows.
echo 'export PATH="/usr/local/opt/postgresql@15/bin:$PATH"' >> ~/.zshrc
Next we need to initialise the database.
$ initdb /usr/local/var/postgres
Finally, create a default postgres
user.
$ /usr/local/Cellar/postgresql/<version>/bin/createuser -s postgres
# for example
# $ /usr/local/Cellar/postgresql@14/14.6/bin/createuser -s postgres
Running Postgres Link to heading
Homebrew can manage Postgres sessions. You can start, run and stop your Postgress instance using Homebrew’s services command.
The difference between start and run is that start adds the Postgres service to login, meaning it will start every time you reboot your Mac. Since I only want the service to run when I need it, I’ll choose the run option.
$ brew services run postgresql@15
If the command was successful, your Terminal displays a message like this:
==> Successfully ran `postgresql@13` (label: homebrew.mxcl.postgresql@13)
You can also see a list of services (started and stopped) using the list command:
$ brew services list
mongodb-community started christopher ~/Library/LaunchAgents/homebrew.mxcl.mongodb-community.plist
mysql none
php none
postgresql@15 started /usr/local/opt/postgresql@15/homebrew.mxcl.postgresql@15.plist
unbound none
When Postgres is running, you can connect to the data with the default postgres
user:
$ psql postgres
We’ll configure Backstage to use Postgres after installing Backstage.
Backstage Link to heading
Backstage is installed using npx
, which is included with Node.
Navigate to the directory where you want to install Backstage and enter the following command.
$ npx @backstage/create-app@latest
During installation, you’ll be prompted to name your Backstage app and the directory in which it’s contained.
Once the installation is complete, change into the new directory and start the app’s development server with yarn.
$ cd app-name && yarn dev
Once the app has finished booting, you should be directed automatically to http://localhost:3000
in your browser.
Configuring Backstage Link to heading
As noted, Backstages uses a volatile, in-memory database that’s destroyed when the Backstage service is stopped. We’ll need to configure Backstage to use our Postgres instance to save data between sessions.
Stop Backstage and install the Backstage PostgresSQL client:
$ yarn add --cwd packages/backend pg
In a text editor, open app-config.yaml
file and edit the database entry with your database’s details.
I commented out the default values and replaced them with the settings needed to connect to my local Postgres instance.
database:
# client: better-sqlite3
# connection: ':memory:'
client: pg
connection:
host: 127.0.0.1
port: 5432
user: postgres
password: postgres
Next, it’s time to configure GitHub integration, which allows Backstage to create new repositories when we create a new component. The official docs suggest using a personal token, which is fine for a local deployment. You can create tokens in your account settings, then add to the app-config.yaml
file.
integrations:
github:
- host: github.com
token: ghp_YOURTOKEN
Restart Backstage, and you should be able to create a component (project) with the repo automatically added to your GitHub account.
Adding project documentation Link to heading
Once you’ve created a project, you can add documentation with a few simple steps.
Firstly, edit your project’s catalog-info.yaml
to reference the TechDocs plugin under the annotations segment. This annotation tells Backstage to download the needed files to generate your documentation.
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: "backstage-test"
annotations:
backstage.io/techdocs-ref: dir:. # <-- add this line
spec:
type: service
owner: user:guest
lifecycle: experimental
In the root of your repo, add an MkDocs configuration file. Minimally, you must include a title and at least one navigation entry for your index file. The reference to the techdocs-core plugin is optional, but Backstage will automatically add it.
site_name: 'example-docs'
nav:
- Home: index.md
plugins:
- techdocs-core
Create a docs
directory in your repo and add an index.md
file containing some basic markdown.
# example docs
This is a basic example of documentation.
Your repo’s directory structure should look something like this:
docs/
- index.md
catalogue-info.yaml
index.js
mkdocs.yml
package.json
Commit your changes, and visit your project’s docs URL.
Troubleshooting Link to heading
If your docs don’t render initially, Backstage’s TechDocs plugin is probably set to use Docker in your app-config.yaml
, and you might not have it installed on your Mac. You can install Docker, or set Backstage to run the docs off a local MkDocs instance.
I opted to run MkDocs locally as I already had it installed, and Docker feels clunky on macOS, at least in my experience.
techdocs:
builder: 'local'
publisher:
type: 'local'
generator:
runIn: local
Note, for this to work, you’ll also need to install MkDocs and the mkdocs-techdocs-core plugin locally on your Mac using pip3, the Python package manager.
$ pip3 install mkdocs-techdocs-core==1.0.1
Once installed, restart Backstage and revisit your project’s docs URL.
Concluding thoughts Link to heading
Backstage has many moving parts, but it’s a powerful tool for developers and technical writers. Running it locally on your Mac allows you to experiment and learn without spinning up a VPS.
If you get stuck, need help or want to talk tech writing with me, don’t hesitate to reach out on LinkedIn.