make more platform agnostic

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>
This commit is contained in:
aramissennyeydd
2026-05-05 09:15:18 -04:00
parent 2ce3506e93
commit 456d9e76f1
+80 -156
View File
@@ -2,185 +2,109 @@
id: deploying
sidebar_label: 004 - Deploying
title: Deploying to production
description: How to deploy your Backstage instance to Kubernetes and other platforms
description: How to deploy your Backstage instance to production
---
Audience: Admins
## Summary
You have a Docker image, a database, and authentication configured. Now it is
time to deploy. The best way to deploy Backstage is _the same way_ you deploy
other software at your organization. This page covers deploying to Kubernetes
as a concrete example and points to resources for other platforms.
You have a Docker image, a database, and authentication configured. Now it
is time to deploy. The _best_ way to deploy Backstage is _the same way_ you
deploy other software at your organization. Backstage is designed to run as
a stateless Node.js application backed by an external PostgreSQL database,
so it fits into most existing deployment pipelines without special tooling.
## Deploying to Kubernetes
This page describes what every Backstage deployment needs, regardless of
platform, and points to the reference guides for specific targets.
Kubernetes is the most common deployment target for Backstage. The deployment
involves a few Kubernetes objects: a namespace, secrets, a deployment, and a
service.
## What every deployment needs
### 1. Create a namespace
Whichever platform you choose, the deployment will need to take care of the
following concerns:
```yaml
# kubernetes/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: backstage
```
- **A container image** built from your repository and pushed to a registry
your runtime can pull from. The image you built in
[Building the Docker image](./001-docker.md) is the artifact that gets
deployed.
- **Configuration and secrets** delivered to the running container as
environment variables or mounted files. This includes database
credentials, auth provider client secrets, and any integration tokens.
- **A reachable PostgreSQL database** that the running instance can connect
to using the credentials from the previous step. See
[Configuring the database](./002-database.md) for details.
- **A network entry point** — typically an ingress, load balancer, or
reverse proxy — that exposes the backend on port `7007` to your users
over HTTPS.
- **A health-checked runtime** that can restart the container if it stops
responding and roll out new versions when you publish a new image.
- **`app.baseUrl` and `backend.baseUrl`** in your
`app-config.production.yaml` set to the public URL where users will
access Backstage. Auth providers and the frontend rely on these matching
the actual entry point:
```shell
kubectl apply -f kubernetes/namespace.yaml
```
```yaml title="app-config.production.yaml"
app:
baseUrl: https://backstage.example.com
backend:
baseUrl: https://backstage.example.com
listen:
port: 7007
```
### 2. Create secrets
## Choosing a deployment target
Store your database credentials and any other secrets (API tokens, auth
client secrets) as Kubernetes Secrets:
Backstage runs anywhere a Node.js container can run. Pick the option that
matches what your organization already operates — you do not need to adopt
new infrastructure to run Backstage.
```yaml
# kubernetes/backstage-secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: backstage-secrets
namespace: backstage
type: Opaque
data:
POSTGRES_USER: <base64-encoded-value>
POSTGRES_PASSWORD: <base64-encoded-value>
```
| Target | Good fit when... |
| :----------------------- | :---------------------------------------------------------------------- |
| Kubernetes | Your organization already runs services on Kubernetes. |
| Amazon ECS / Fargate | You are on AWS and prefer managed container scheduling. |
| Google Cloud Run | You want a fully managed, request-driven container runtime on GCP. |
| Azure Container Apps | You are on Azure and want a managed container platform. |
| A traditional VM or PaaS | You prefer running the Node.js process directly behind a reverse proxy. |
| Docker Compose | You are running a small installation or proof of concept. |
:::note
Backstage maintains a reference guide for the Kubernetes path in
[Deploying with Kubernetes](../../deployment/k8s.md), which walks through
namespaces, secrets, the deployment, the service, and connecting to
PostgreSQL inside the cluster.
Kubernetes secrets are base64-encoded but not encrypted. Enable
[Encryption at Rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)
for your cluster and consider tools like
[SealedSecrets](https://github.com/bitnami-labs/sealed-secrets) for storing
secrets in Git.
For other platforms, the
[community-contributed deployment guides](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/)
in the Backstage repository cover targets such as ECS, Cloud Run, and
Docker Compose, and the [deployment overview](../../deployment/index.md)
explains the underlying model that all of these guides share.
:::
## Operational concerns
```shell
kubectl apply -f kubernetes/backstage-secrets.yaml
```
A few operational details apply to every deployment and are worth getting
right before opening Backstage up to your users:
### 3. Create the deployment
- **Run multiple replicas** behind your load balancer. Backstage is
stateless, so multiple instances can serve traffic against the same
PostgreSQL database. We cover this further in
[Scaling Backstage](./007-scaling.md).
- **Store secrets securely.** Container platforms typically offer a
secrets primitive — Kubernetes Secrets, AWS Secrets Manager, GCP Secret
Manager, Azure Key Vault, and so on. Reference these from your
configuration with environment variables rather than committing
credentials.
- **Enable health checks.** Wire your platform's readiness and liveness
probes to the Backstage health endpoints so unhealthy instances are
taken out of rotation and restarted automatically.
- **Run behind HTTPS.** Terminate TLS at your ingress, load balancer, or
reverse proxy and make sure the public URL is what `app.baseUrl` and
`backend.baseUrl` are set to.
```yaml
# kubernetes/backstage.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backstage
namespace: backstage
spec:
replicas: 1
selector:
matchLabels:
app: backstage
template:
metadata:
labels:
app: backstage
spec:
containers:
- name: backstage
image: <your-registry>/backstage:<tag>
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 7007
envFrom:
- secretRef:
name: backstage-secrets
readinessProbe:
httpGet:
port: 7007
path: /.backstage/health/v1/readiness
livenessProbe:
httpGet:
port: 7007
path: /.backstage/health/v1/liveness
```
Replace `<your-registry>/backstage:<tag>` with the full image URL from your
container registry.
```shell
kubectl apply -f kubernetes/backstage.yaml
```
### 4. Create a service
```yaml
# kubernetes/backstage-service.yaml
apiVersion: v1
kind: Service
metadata:
name: backstage
namespace: backstage
spec:
selector:
app: backstage
ports:
- name: http
port: 80
targetPort: http
```
```shell
kubectl apply -f kubernetes/backstage-service.yaml
```
### 5. Expose the service
The Service is not accessible outside the cluster by default. Use a Kubernetes
[Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
or an
[external load balancer](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/)
to expose Backstage to your users.
Make sure the `app.baseUrl` and `backend.baseUrl` values in your
`app-config.production.yaml` match the URL where users will access Backstage:
```yaml title="app-config.production.yaml"
app:
baseUrl: https://backstage.example.com
backend:
baseUrl: https://backstage.example.com
listen:
port: 7007
```
## Other deployment platforms
Backstage is a standard Node.js application running in a Docker container, so
it works on any platform that supports containers:
- **Amazon ECS**: Create a task definition referencing your Docker image, set
up an ECS service, and place it behind an Application Load Balancer.
- **Google Cloud Run**: Deploy the image as a Cloud Run service with the
appropriate environment variables.
- **Azure Container Apps**: Deploy the image and configure ingress through
the Azure portal or CLI.
- **Docker Compose**: Suitable for smaller installations. Run Backstage and
PostgreSQL together using a `docker-compose.yaml`.
Community-contributed deployment guides are available in the
[contrib/docs/tutorials](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/)
folder of the Backstage repository.
## Further reading
For a detailed guide including setting up PostgreSQL in Kubernetes, see
the [Deploying with Kubernetes](../../deployment/k8s.md) reference
documentation.
If you need to run Backstage behind a corporate proxy, see the
[corporate proxy guide](../../tutorials/corporate-proxy.md).
## Next steps
Your Backstage instance is deployed. Next, let's look at how to manage
configuration effectively.
configuration effectively across environments.
- [Config-first development](./005-config-first.md)