Certified Backstage Associate (CBA)

Production Backstage

Docker Deployment

Containerizing your Backstage backend with Docker makes it easy to run and scale across any container orchestration platform—whether it’s Kubernetes, Amazon ECS, or your own on-premise solution. When you scaffold a new Backstage app using create-app, a production-ready Dockerfile is generated automatically under packages/backend/Dockerfile. You can build on this file to package your Backstage instance without starting from scratch.

The image is a flowchart titled "Backstage With Docker," illustrating the process from Backstage Source to Docker Container, involving a Dockerfile and Docker Build.

Prerequisites

  • Node.js 20 (or later)
  • Yarn
  • Docker (with BuildKit enabled)
  • A cloned Backstage repository initialized via npx @backstage/create-app

Overview of the Generated Dockerfile

Backstage’s default Dockerfile bundles the backend in a production-ready image. Below is a high-level summary:

StagePurposeKey Instructions
Base ImageNode.js runtimeFROM node:20-bookworm-slim
System DependenciesBuild tools for native modulesapt-get install -y python3 g++ build-essential libsqlite3-dev
App User & WorkspaceSecurity and working directoryUSER node<br>WORKDIR /app
Copy ArtifactsYarn cache, lockfile, skeleton bundleCOPY .yarn .yarn<br>COPY yarn.lock package.json skeleton.tar.gz ./
Install Production DepsOptimize workspace dependencies for prodyarn workspaces focus --all --production
Bundle ExtractionUnpack backend code and configurationtar xzf bundle.tar.gz<br>COPY app-config.yaml .
Runtime CommandStart the Backstage backendCMD ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.production.yaml"]

packages/backend/Dockerfile

# Use Node 20 on Debian Bookworm
FROM node:20-bookworm-slim

# Ensure node-gyp can find Python3
ENV PYTHON=/usr/bin/python3

# Install build dependencies for @backstage/plugin-scaffold-backend
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    apt-get update && \
    apt-get install -y --no-install-recommends python3 g++ build-essential && \
    rm -rf /var/lib/apt/lists/*

# Install sqlite3 dependencies (optional)
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    apt-get update && \
    apt-get install -y --no-install-recommends libsqlite3-dev && \
    rm -rf /var/lib/apt/lists/*

# Switch to non-root 'node' user
USER node
WORKDIR /app

# Copy Yarn artifacts and Backstage config
COPY --chown=node:node .yarn ./.yarn
COPY --chown=node:node yarnrc.yml backstage.json ./

ENV NODE_ENV=production
ENV NODE_OPTIONS="--no-node-snapshot"

# Extract skeleton for faster installs
COPY --chown=node:node yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./
RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz

# Install production dependencies only
RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \
    yarn workspaces focus --all --production && \
    yarn cache clean

# Copy and unpack the compiled backend bundle and its config
COPY --chown=node:node packages/backend/dist/bundle.tar.gz ./
COPY --chown=node:node packages/backend/dist/app-config.yaml ./app-config.yaml
RUN tar xzf bundle.tar.gz && rm bundle.tar.gz

# Start the backend service
CMD ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.production.yaml"]

Note

Be sure to enable Docker BuildKit in your environment to leverage layer caching with the --mount=type=cache syntax.
On Docker Desktop you can toggle this under Settings › Docker Engine.

1. Build the Backstage Backend Bundle

Run these commands from your repository root to install dependencies, generate types, and compile the backend code:

# Install dependencies in strict mode
yarn install --immutable

# Generate TypeScript definitions
yarn tsc

# Compile the backend into dist/{bundle.tar.gz,skeleton.tar.gz}
yarn build backend

2. Build the Docker Image

With the Dockerfile and backend bundle ready, build your container image:

docker build . \
  -f packages/backend/Dockerfile \
  --tag backstage:latest

3. Run & Deploy the Container

Launch your Backstage backend locally:

docker run -p 7000:7000 backstage:latest

Once verified, push the image to your container registry (Docker Hub, ECR, GCR, etc.) and deploy it to your preferred platform.

Watch Video

Watch video content

Previous
Demo Authentication