Deploying Backstage on Kubernetes for a production developer portal
A platform team that runs Backstage for many engineers needs the portal to behave like any other internal service: multiple replicas, a database that survives node loss, secrets kept out of manifests, and a stable address behind an ingress. Backstage is an open source framework released under the Apache License 2.0, and the project does not sell a paid edition, so the cost of running it is the infrastructure, the people who operate it and the work of building it into your environment. DeployOpen plans and builds this inside your own clusters, in your cloud accounts or data centers, so the portal, its configuration and its data stay under your control. The core pieces are a Kubernetes Deployment for the Backstage backend container, a Service that gives the pods one stable address, an ingress that terminates TLS for your portal hostname, and PostgreSQL held outside the cluster's node-local storage.
A single-replica test install is enough to evaluate the catalog and templates, but it is not enough once teams depend on the portal. One pod means every rolling restart, node drain or failed pod takes the portal offline, and the catalog and scaffolder have no second instance to absorb work. Running more than one replica also means every replica must read the same configuration and reach the same database, and it raises questions about shared caching that the sibling pages on the backend split and cache address in depth. Credentials for the database, the authentication provider and integrations belong in Kubernetes Secrets. Kubernetes stores Secrets unencrypted in etcd by default, so confirm that encryption at rest is enabled on your control plane and that list and watch access to Secrets is limited by RBAC. Before you start, ask your cluster team which secrets store they already run and whether the Secrets Store CSI Driver fits your model.
Plan the health probes and the database together. Liveness and readiness probes should point at the endpoints the Backstage backend exposes, and the readiness check should fail when the portal cannot reach PostgreSQL, so traffic stops reaching pods that cannot serve it. Moving PostgreSQL off node-local storage means choosing between a managed service and an operator-run cluster, and that choice sets backup, failover and upgrade responsibilities. Confirm the database version requirements with the Backstage release you target, and confirm the Kubernetes version your platform runs against the current support window published on the Kubernetes releases page, because a cluster that falls out of support will delay every later upgrade. Then rehearse a pod eviction and a database failover in a non-production cluster before the portal carries team workflows.
Which Kubernetes deployment options fit which situation
This table compares the main deployment choices for Backstage on Kubernetes: how workloads are split, how many replicas run, where PostgreSQL lives, and how secrets are supplied. Read each row against your team size, change cadence and on-call model to see which option matches your situation and what ongoing work it creates.
| Decision | Option and when it fits | Operations cost to plan for |
|---|---|---|
| Workload layout | One Deployment for backend and frontend fits a pilot, a small catalog or a team that wants one image and one rollout to manage. | Every frontend change redeploys the backend, and scaling needs are shared. Confirm the packaging with your build pipeline before choosing this. |
| Workload layout | Separate workloads for frontend and backend fit teams that want independent rollouts, or that plan to serve the static frontend from NGINX or a CDN later. | Two manifests, two images and two sets of probes to keep in step, plus routing rules at the ingress. Frontend configuration must be handled explicitly. |
| Replica count | A single replica fits a non-critical pilot or an internal sandbox where short restarts are acceptable. | Restarts and node drains cause downtime for every user. Plan a maintenance window and confirm how your team responds to a failed pod. |
| Replica count | Several replicas fit production portals that many engineers depend on daily, provided they share one cache and one database. | Each replica needs a shared cache store and a database that all instances can reach. Confirm session handling and cache setup before scaling out. |
| PostgreSQL hosting | An in-cluster operator fits teams that already run and back up PostgreSQL on Kubernetes and have people who can operate it. | Your team owns high availability, point-in-time recovery, minor and major upgrades, and restore tests. Ask the operator vendor which of these it automates. |
| PostgreSQL hosting | A managed PostgreSQL service fits teams that want the provider to handle patching, backups and failover within the service terms. | Recurring service fees, network path and private connectivity setup, and a dependency on the provider's maintenance schedule. Confirm the PostgreSQL version it supports. |
| Secrets source | Kubernetes Secrets fit small deployments where the cluster already has encryption at rest enabled and tight RBAC on Secret access. | Secrets are stored unencrypted in etcd by default, so you must enable encryption at rest and restrict list and watch access yourself. |
| Secrets source | An external store through the Secrets Store CSI Driver fits organizations that already keep credentials in a central vault and need one rotation process. | A driver to install and maintain, a provider to configure for each store, and a second system to back up and audit. Confirm the store's supported features with its vendor. |
Setup sequence for a Backstage Deployment
This sequence takes a Backstage instance from an empty cluster to a running, restart-tolerant deployment with encrypted Secrets, health probes, a stable entry point and a database that survives node loss. Each step ends with a check so the next step starts from a verified state.
Create the namespace and scoped RBAC
Create a dedicated namespace for Backstage and bind only the service accounts and human roles it needs, so that Backstage's workloads and Secrets are separated from other tenants. Your platform team typically owns this step, with the security team reviewing the bindings. Confirm the result by listing the role bindings in the namespace and checking that no broad cluster-admin binding points at the Backstage service account. Use the Kubernetes Pod Security Standards to set the namespace enforcement level before any workload lands in it.
Configure encryption at rest for Secrets
Kubernetes stores Secrets unencrypted in etcd by default, so enable encryption at rest in the API server configuration before you store any database or identity provider credentials. If your distribution is managed, confirm with the provider whether and how it offers this setting, and whether it can use a key management service. Verify by creating a test Secret and reading the raw value from etcd through your cluster's supported tooling, confirming it is not readable as plain text. Also restrict list and watch access on Secrets with least-privilege RBAC, as the Kubernetes Secrets good practices page recommends.
Create Secrets for database and auth credentials
Create Kubernetes Secrets for the PostgreSQL connection values, the authentication provider client IDs and secrets, and the backend service keys, then reference them from the Deployment rather than baking them into the container image or the app-config files. Keep the values out of version control and source them from your secrets manager or the Secrets Store CSI Driver if your policy requires external storage. Confirm the Secrets exist and that the pod sees them as environment variables or mounted files, without printing their values in logs.
Deploy Backstage with health probes
Create the Deployment with replicas, resource requests, and both liveness and readiness probes pointed at the backend health endpoint. Readiness controls whether a pod receives traffic, while liveness restarts a pod that has stopped responding, so keep the liveness check lenient to avoid restart loops during slow startup. Confirm that pods reach Ready, then delete one pod and check that the replacement passes its probes and that a catalog entity still loads in the portal UI. This restart check is the first real test of whether the state lives in the database and not in the pod.
Expose Backstage through a Service and ingress
Create a ClusterIP Service that selects the Backstage pods, then publish it through your ingress controller with TLS terminated at the ingress. The public base URL in the Backstage configuration must match the ingress hostname, because sign-in redirects and links depend on it. Confirm by loading the hostname over HTTPS, completing sign-in through your configured provider, and checking that the redirect returns to the same host. Disable any guest access before exposing the URL outside your network.
Move PostgreSQL off node-local storage
Until this step, the database may be running on a single node's local disk, which is lost if that node fails. Move it to a PostgreSQL deployment that replicates data and can recover onto another node, either a managed service or an operator-managed cluster in your infrastructure. Point the Backstage connection settings at the new endpoint and confirm the per-plugin logical databases were created there. Test by cordoning and draining the node that held the old data, then confirming Backstage reconnects and the catalog still returns the same entities.
Rehearse a restart and confirm recovery
Finish by running a controlled restart of the Deployment and a node drain, then confirm that the catalog, sign-in and scaffolder history return unchanged. Record the steps and the observed behavior so the platform team can repeat them before each upgrade. Ask your database provider for its documented recovery procedure and confirm that a backup restore has been tested in your environment, since replication alone does not replace backups.
Why Secrets and PostgreSQL storage decide whether the portal survives a node failure
Kubernetes stores Secrets unencrypted in etcd by default, so the Backstage credentials you mount into the Deployment (the GitHub or GitLab tokens, the OIDC client secret, the backend shared secret and the PostgreSQL password) are only as protected as the etcd data and the API paths that read them. Before go-live, confirm that encryption at rest is configured for Secrets on your control plane, and check that the Secrets Store CSI Driver or your external secret store is the source of truth if your platform uses one. Then review RBAC: any principal that can list or watch Secrets in the Backstage namespace can read every value in it, so restrict those verbs to the few service accounts that need them. Your platform team should also confirm who can kubectl get secret in production, because that permission is easy to grant during an incident and rarely revoked.
Backstage keeps its state in PostgreSQL. Each backend plugin gets its own logical database through Knex, so the catalog, the search index and other plugin data all live in that server, not in the pods. If the database sits on node-local storage, the portal is tied to the node that holds the volume, and a node failure takes the catalog and sign-in state down with it even when healthy replicas are scheduled elsewhere. Decide early whether PostgreSQL will be a managed service or an in-cluster operator with replicated, network-attached storage, and confirm the storage class and backup approach before you size the Deployment. The PostgreSQL topic covers the database choice in detail.
Sign-in decisions belong in the same review. The Backstage authentication documentation advises configuring sign-in resolvers so every provider resolves to the same identity, and not offering guest access in production. Confirm that your resolver maps each provider to one catalog user, so a restart or a changed login path does not create duplicate identities, and remove any guest provider from the production app-config before the first rollout. These controls matter for node failure too: a replacement pod that starts with a different auth configuration will issue different identities, so the resolver and Secret references must be identical across replicas. Ask your team to test sign-in against a second replica before relying on the portal.
Security controls to set before users arrive
These controls protect the credentials, cluster and sign-in path that a Backstage deployment depends on. Set them before the portal is shared, because catalog data and integration tokens are worth more to an attacker than the portal's pages. Confirm each setting against your own security policy and the vendor documentation for your Kubernetes distribution.
Encryption at rest for Secrets
Kubernetes stores Secrets unencrypted in etcd by default. Configure encryption at rest for the Secrets resource before you load the Backstage app-config secrets, such as the catalog integration tokens and the database password. Check that the setting is active on every control plane node and that existing Secrets were rewritten after the change, because older objects stay in plaintext until they are updated. Confirm the key management approach with your platform team.
Pod Security Standards for the namespace
Apply the Pod Security Standards to the namespace where Backstage runs, starting with the level your policy requires and testing the pods against it before enforcement. A Backstage pod should run as a non-root user, drop unneeded capabilities and avoid privilege escalation. Confirm that the Backstage image and any init containers meet the chosen level, and record the namespace label as evidence of the control.
RBAC limits on Secrets
Grant the Backstage service account only the read access it needs to its own Secrets, and keep list and watch permissions off broad roles. Any user or workload that can list Secrets in the namespace can read every credential stored there, so review role bindings for cluster admins, CI systems and monitoring tools. Confirm the bindings after each Helm or manifest change, since defaults can grant wider access than intended.
Ingress TLS
Terminate TLS at the ingress for the Backstage hostname and redirect plain HTTP to HTTPS. Backstage sign-in cookies and tokens travel through this path, so an unencrypted listener exposes them. Use a certificate issued by your internal or public CA, renew it automatically, and confirm that the backend base URL in the app configuration uses the HTTPS address that users see, so OAuth callbacks match the registered redirect URLs.
No guest sign-in in production
Do not enable the guest authentication provider in production. The Backstage authentication documentation advises against offering guest access there, because a guest session is not tied to a named identity. Configure one identity provider with a sign-in resolver so every sign-in maps to the same catalog user. Test the production configuration with a non-admin account before release, and confirm that the guest provider is absent from the production app-config.
CIS Kubernetes Benchmark review
Review the cluster against the CIS Kubernetes Benchmark before users arrive, using a scan tool or manual checks for the control plane, worker nodes and policies. The benchmark covers API server flags, kubelet settings and etcd access, which sit below the Backstage deployment but affect its exposure. Record which recommendations you accept, which you change and which you defer with a reason, and confirm the results with your security team.
Questions teams ask before deploying Backstage on Kubernetes
What does deploying Backstage on Kubernetes cost, and what drives the price?
The cost is mostly the people time to build and hand over the deployment, plus the infrastructure you already pay for. Backstage itself is open source under the Apache License 2.0 and has no license fee, so the spend is on the cluster capacity, the PostgreSQL service, any cache, and the engineering work. The main drivers are how many environments you run, whether you need a shared cache or split backend, how your secrets and identity are already set up, and how much of the pipeline you want automated. Ask for a fixed-scope quote that lists each deliverable, which costs recur (cluster capacity, database hosting, staff time for upgrades) and which are one-time (design, build, handover). DeployOpen does not publish prices; a quote follows from the written scope.
How long does a Backstage Kubernetes deployment take to build?
Duration depends on how much of the surrounding platform is already in place. A team with a working cluster, an existing identity provider, a database owner and a container build pipeline has a much shorter path than a team that must first agree on namespaces, Secrets handling and ingress. The biggest variables are the number of environments, whether encryption at rest for Secrets is already configured on the cluster, whether PostgreSQL is a managed service or an in-cluster operator, and how many decisions need sign-off from security or compliance. Your statement of work should set the timeline against named milestones, so the dependencies on your team are visible from the start.
What must our team provide before the engagement starts?
Three things block most projects if they are not ready. First, cluster access: a target namespace, permission to create Deployments, Services, ingress resources and Secrets, and a decision on which cluster or clusters will run Backstage. Second, an identity provider: you need an OIDC or other supported sign-in provider and a named owner who can register the application and approve the sign-in resolver logic. Third, a database owner: someone accountable for the PostgreSQL instance, backups, connection limits and version upgrades. Confirm these owners and access paths in writing before work begins, because the scope and the quote depend on them.
Can an internal platform team deploy Backstage on Kubernetes alone?
Often yes, if the team already runs Kubernetes workloads in production and has experience with Secrets, ingress and database operations. The work is standard container and Kubernetes engineering, but Backstage adds its own configuration, sign-in and plugin choices that need Node.js and TypeScript familiarity. Teams usually struggle less with the first deployment than with the second year: keeping the image, the configuration and the dependencies current. Assess your team against those skills honestly. An external partner is useful when the team lacks spare capacity, needs a fixed delivery date, or wants a documented handover that a later team can follow.
How do Backstage's monthly and weekly releases affect the Deployment?
Backstage ships a main release line once a month, on the Tuesday before the third Wednesday, and a next release line every week on Tuesdays. Upgrades are made by moving all @backstage packages together with yarn backstage-cli versions:bump, and the Backstage Upgrade Helper shows template changes between versions. Each upgrade changes the image you build, so the Deployment should pull a tagged image built from a pinned version, not a moving branch. The versioning policy says high and critical vulnerabilities are backported to releases from the last six months where feasible, so staying on a supported line matters. Plan a recurring upgrade window, a staging environment that runs the new image first, and a rollback path using the previous image tag.
What does Kubernetes version support mean for the cluster that runs Backstage?
Kubernetes maintains the three most recent minor releases. As of September 2026 those were 1.37 (end of life October 28, 2027), 1.36 (June 28, 2027) and 1.35 (February 28, 2027), according to the Kubernetes releases page. Releases come roughly three times a year on a cycle of about 14 weeks, so a cluster that stays on one minor version will fall out of support within about a year of its end of life. Version skew rules require the API server to be upgraded one minor version at a time, and kubelets may be up to three minor versions older. Ask your platform team which minor version the cluster runs, when it leaves support, and who owns each control plane upgrade before you set the Backstage upgrade schedule.
Where do Backstage Secrets live, and do we need encryption at rest?
Yes. By default, Kubernetes stores Secrets unencrypted in etcd, so the Backstage Secrets that hold integration tokens, database passwords and sign-in client secrets are exposed to anyone who can read etcd backups. Configure encryption at rest on the API server, restrict list and watch access with least-privilege RBAC, and consider an external store through the Secrets Store CSI Driver if your policy requires one. Keep these values out of the container image and out of committed app-config files. Confirm with your cluster owner whether encryption at rest is already enabled on the target cluster, since that is outside the Backstage deployment itself.
Limits to confirm in your environment
A Backstage deployment on Kubernetes inherits limits from the cluster, the database, the runtime and the sign-in setup. Confirm each one against your own environment before you write manifests, because a mismatch in any of them usually surfaces late, during the first upgrade or the first recovery test.
Kubernetes version your distribution supports
Upstream Kubernetes maintains only the three most recent minor releases, so your distribution vendor decides how long your cluster stays supported. Ask which Kubernetes minor versions the distribution supports, how long each receives patches, and whether the APIs your Backstage manifests use are available on that version. Check the distribution's own support calendar, since it may lag upstream. If your cluster is near end of life, plan the cluster upgrade before the Backstage build starts.
Node.js version for the release
Backstage supports exactly two adjacent even-numbered Node.js releases, and the supported pair changes as the project moves to new release lines. Pin the Node.js major version in your container base image to one of the pair that matches the Backstage release you deploy. Confirm the pair in the versioning policy for your target release before you choose the base image, and make sure your CI build uses the same major version as the runtime image.
PostgreSQL version for search
Backstage stores each backend plugin in its own logical database, and some plugins, including search, need a minimum PostgreSQL version. Confirm the version your target release requires, then check it against the managed database service or operator you plan to use. Also confirm that the database role Backstage uses can create the logical databases it needs, because a restricted role can block plugin startup after the first deployment.
Cluster and etcd against your backup plan
Backstage keeps its data in PostgreSQL, but the Kubernetes Secrets that hold tokens and database credentials live in etcd. Confirm that your etcd topology has at least three members in production, that snapshots run on a schedule, and that you have tested a restore with etcdutl. Also confirm that encryption at rest is enabled for Secrets, because the default stores them unencrypted. If your recovery target is shorter than your snapshot interval, the plan does not meet the requirement.
Ingress and sign-in provider settings
The external URL in the Backstage configuration must match the hostname, TLS certificate and path that your ingress serves, or the OAuth redirect will fail. Check that the callback URL registered with your identity provider matches the URL exactly, including scheme and port. Confirm that the sign-in resolver maps every provider to the same identity, and that guest access is disabled in production. Mismatches here are the most common first-day failure on a new deployment.
Upgrade path for the release line
Backstage moves its packages together through a single version bump, and the main release line ships monthly while the next line ships weekly. Confirm which line your organization will follow, who will apply patch releases, and how quickly high and critical fixes will reach your cluster. Check that your plugins and custom code are compatible with the release you choose, and that your change process can absorb a monthly cadence without a dedicated owner.
Where to read the upstream documentation first
Start with the Backstage architecture overview before you write any manifests. It explains which components sit in the backend process, where PostgreSQL and the cache fit, and which built-in features depend on them, so you can size the Deployment, the database connection settings and the probes against how the backend actually behaves. Read it alongside the Backstage architecture overview and note which plugins you intend to enable, because each one changes what the pods must reach at startup.
The Backstage authentication documentation is the second read. Confirm how your chosen provider maps to a single catalog identity through sign-in resolvers, that guest access is off in production, and where the auth-related keys will come from. Those answers determine which values belong in the Kubernetes Secret and which can live in ConfigMap-style configuration, so settle them before the first deployment rather than after users arrive.
Read the Backstage keeping Backstage updated guide before you pin an image tag. It describes the yarn backstage-cli versions:bump workflow and the Upgrade Helper, which together decide how you will roll new images through your cluster. On the cluster side, the Kubernetes good practices for Secrets page covers encryption at rest and least-privilege access to the Secrets you create, and the kubeadm high availability guide matters if you run the control plane yourself. Confirm which of these applies to your platform before you design the namespace layout.
How DeployOpen delivers Backstage on Kubernetes
DeployOpen plans, builds, documents and supports Backstage on Kubernetes inside your own cloud accounts, data centers or air-gapped networks. We start from a written scope that covers the namespace, Secrets, ingress, probes, replicas and the move of PostgreSQL off node-local storage, then hand over runbooks your platform team can operate.
How we scope
- Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts.
- We confirm your Kubernetes distribution, version and cluster access model, including how users authenticate to the cluster.
- We document which Secrets, encryption at rest settings and RBAC roles the deployment needs before any manifest is written.
How we build
- We package the Backstage deployment with its Service, ingress, health probes and replica settings as versioned manifests.
- We move the PostgreSQL database off node-local storage and verify connection settings and backup restores in your environment.
- We test rollouts, pod restarts and node drains to confirm the portal stays reachable during routine cluster maintenance.
How we hand over
- You receive the manifests, configuration notes and a record of decisions on Secrets handling and namespace boundaries.
- We provide runbooks for deploying new releases, rotating credentials and restoring the database from backup.
- Knowledge transfer sessions walk your platform engineers through troubleshooting probes, rollbacks and scaling decisions.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers after the initial handover.
- Retainers can cover tracking Backstage release lines and Kubernetes version changes that affect the deployment.
- We can review your deployment after Kubernetes upgrades, etcd changes or ingress controller updates to confirm nothing has drifted.

