Backstage Docker multi-stage image build fails in CI
The recommended Backstage backend image is a multi-stage build: a build stage runs the bundle, a runtime stage installs production deps. It fails most often when the runtime stage lacks the toolchain for native modules or when the bundle tarball is missing.
What this error means
docker build fails with a node-gyp error in the runtime stage, "COPY failed: no source files were specified" for the bundle, or "Cannot find module" at container start.
=> ERROR [runtime 4/6] RUN yarn install --production --frozen-lockfile
gyp ERR! stack Error: not found: make
The command '/bin/sh -c yarn install --production' returned a non-zero code: 1Common causes
The runtime stage lacks build tools for native deps
better-sqlite3 recompiles during the production install in the runtime stage, which needs python3 and a compiler that a slim base image omits.
The bundle tarball was not produced or copied
The Dockerfile copies packages/backend/dist/bundle.tar.gz, but the build step that creates it did not run, so COPY finds no source.
How to fix it
Install build tools in the runtime stage
Add python3 and a compiler before the production install so native modules can build.
FROM node:20-bookworm-slim
RUN apt-get update && apt-get install -y python3 g++ make
COPY packages/backend/dist/bundle.tar.gz app/
RUN tar xzf app/bundle.tar.gz -C app/ && yarn install --productionCreate the bundle before docker build
- Run the backend build so the bundle tarball exists.
- Then run docker build referencing that artifact.
- Confirm the COPY path matches the produced file.
yarn build:backend --config ../../app-config.yaml
docker build . -f packages/backend/Dockerfile --tag backstageHow to prevent it
- Build the backend bundle before invoking docker build.
- Install python3 and a compiler in any stage that runs a production install with native deps.
- Match COPY paths to the artifacts the build actually produces.