I recently set up Backstage.io on our cluster. It wasn’t super-easy, so I decided to “go deep” and tried to make this a learning opportiunity.
I’m also definitely not a DevOps expert, so I had to learn some stuff myself along the way. Here’s my best approximation at a useful guide for anyone who’s going to walk the same path! Hopefully I can save you some time.
In this part we’re going to:
- Set up our repository
- Build a docker image
- Install Backstage on a cluster
- Test our dev-deploy-test loop
What you’ll need?
- A working K8s cluster (
minikube startshould be good enough if you’re just learning)
- A GitHub project with some software components you want to track
And some patience, cause this ain’t gonna be a smooth ride…
First thing first - get the code and store it in a repository
This might be surprising - aren’t we going to just
helm install this?
So, no. To get anything done with Backstage beyond
hello world, you need to
mess around with the actual source code. So you’re going to want a repo of
your own; otherwise, you won’t be able to track changes which we’ll do later
(like adding authentication to the app).
Install the latest
node LTS by running:
nvm install 16
nvm use 16
BTW: I opened a PR for the Backstage team to include a
.nvmrcfile, so you should be able to just run
nvm usenext time. :) Track it here:
If you have multiple Node versions running on your machine remember to do this for each shell session you open.
Choose a name, let it run
yarn install, moan internally about modern package
management and install times while it runs.
Then to test it you can
cd into your new app and run
yarn dev. You ought to
see something like this:
Now, since we’re going to need to perform many changes, most of them on the codebase, now’s a good time to get the code into a repository. So open a GitHub repo, and run the following:
# if you haven't already, git config --global init.defaultBranch main
git add .
git commit -sv
git remote add origin <your repo here>
git push -u origin main
git checkout -b dev
Building a docker image and pushing to a repository
Now that we have the code set up, we need to build an image and push it to a repository our cluster can use. In this example I’ll be using AWS ECR. Once the repository has been created, here’s your magic one-liner:
yarn install --frozen-lockfile &&
yarn build &&
docker buildx build . -f packages/backend/Dockerfile --tag my-backstage --platform linux/amd64 && docker tag my-backstage:latest <ECR_URL_HERE>.amazonaws.com/my-backstage:latest &&
docker push <ECR_URL_HERE>.amazonaws.com/my-backstage:latest
Setting up the application on K8s using
Grab the chart
helm repo add backstage https://vinzscam.github.io/backstage-chart
helm pull --untar backstage/backstage
Install, and make sure it works
Now is a good time to make sure the image works OK in the cluster. You need to
update the image in the
- registry: ""
- repository: ""
- tag: ""
+ registry: ''
+ repository: <ECR_URL_HERE>.amazonaws.com/my-backstage
+ tag: latest
helm install -f values.yaml my-backstage-release .
And test by port-forwarding the app to your local machine. You’re going to need to port forward port 3000 and port 7007.
It should look like this:
Run the dev-deploy-test loop
So, we have everything we need to start messing around with changes. But now is the best time to stop and make sure it all operates smoothly. So let’s make a very small change, and see what the dev-deploy-test loop looks like for us.
Let’s change the title of the application:
diff --git a/app-config.yaml b/app-config.yaml
index 4a058de..0feb730 100644
@@ -1,5 +1,5 @@
- title: Scaffolded Backstage App
+ title: My Backstage App
Then re-run the magic oneliner from before (the one that starts with
to rebuild the docker and push it.
Finally, restart your deployment:
❯ k rollout restart deployment/reco-backstage-release
Click on search, and make sure the change actually worked!
Now we need to start configuring Backstage to make it useful - set up authentication, GitHub integration, and more.
The first thing you really ought to do is to make the service accessible via DNS from outside the cluster - otherwise, you’ll have to redo the port forward each time, and that’s not a pleasent experience at all. So get on that, first!
Will there be a part 2?
Probably not. Most of the config I did after setting up this Helm is too specific to my org (reco.ai), so I assume it won’t really be useful for you. My DMs are open - if anyone will ask, I’ll write the second part up :)