2

I created a Dockerfile following the steps in https://backstage.io/docs/deployment/docker/#multi-stage-build

When running the Dockerfile at the root "docker image build -t backstage .", I'm getting the error below. I confirm that index.ts exists in packages\backend\src folder.

 > [build  9/10] RUN yarn build:backend --config ../../app-config.yaml:
#18 0.618 yarn run v1.22.19
#18 0.646 warning Skipping preferred cache folder "/home/node/.cache/yarn" because it is not writable.
#18 0.646 warning Selected the next writable cache folder in the list, will be "/tmp/.yarn-cache-1000".
#18 0.662 $ yarn workspace backend build --config ../../app-config.yaml
#18 0.834 warning Skipping preferred cache folder "/home/node/.cache/yarn" because it is not writable.
#18 0.834 warning Selected the next writable cache folder in the list, will be "/tmp/.yarn-cache-1000".
#18 1.095 warning Skipping preferred cache folder "/home/node/.cache/yarn" because it is not writable.
#18 1.096 warning Selected the next writable cache folder in the list, will be "/tmp/.yarn-cache-1000".
#18 1.108 $ backstage-cli package build --config ../../app-config.yaml
#18 2.601
#18 2.601 Error: Error: Could not resolve entry module (src/index.ts).
#18 2.601
#18 2.601
#18 2.624 error Command failed with exit code 1.
#18 2.624 info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
#18 2.643 error Command failed.
#18 2.643 Exit code: 1
#18 2.643 Command: /usr/local/bin/node
#18 2.643 Arguments: /opt/yarn-v1.22.19/lib/cli.js build --config ../../app-config.yaml
#18 2.643 Directory: /app/packages/backend
#18 2.643 Output:
#18 2.643
#18 2.643 info Visit https://yarnpkg.com/en/docs/cli/workspace for documentation about this command.
#18 2.660 error Command failed with exit code 1.
#18 2.660 info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

The Dockerfile is as follows, and it is located at the root.

# Stage 1 - Create yarn install skeleton layer
FROM node:16-bullseye-slim AS packages

WORKDIR /app
COPY package.json yarn.lock ./

COPY packages packages

# Comment this out if you don't have any internal plugins
# TO-DO LATER - FIX ERROR: failed to compute cache key: "/plugins" not found: not found
#COPY plugins plugins

RUN find packages \! -name "package.json" -mindepth 2 -maxdepth 2 -exec rm -rf {} \+

# Stage 2 - Install dependencies and build packages
FROM node:16-bullseye-slim AS build

# install sqlite3 dependencies
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    apt-get update && \
    apt-get install -y --no-install-recommends libsqlite3-dev python3 build-essential && \
    yarn config set python /usr/bin/python3

USER node
WORKDIR /app

COPY --from=packages --chown=node:node /app .

# Stop cypress from downloading it's massive binary.
ENV CYPRESS_INSTALL_BINARY=0
RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \
    yarn install --frozen-lockfile --network-timeout 600000

COPY --chown=node:node . .

RUN yarn install --frozen-lockfile
RUN yarn tsc 

# ---- FAILS HERE ----
#RUN yarn build:backend --config ../../app-config.yaml
# --------------------

#RUN yarn --cwd packages/backend build
# If you have not yet migrated to package roles, use the following command instead:
#RUN yarn --cwd packages/backend backstage-cli backend:bundle --build-dependencies

RUN mkdir packages/backend/dist/skeleton packages/backend/dist/bundle \
    && tar xzf packages/backend/dist/skeleton.tar.gz -C packages/backend/dist/skeleton \
    && tar xzf packages/backend/dist/bundle.tar.gz -C packages/backend/dist/bundle

# Stage 3 - Build the actual backend image and install production dependencies
FROM node:16-bullseye-slim

# Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image,
# in which case you should also move better-sqlite3 to "devDependencies" in package.json.
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    apt-get update && \
    apt-get install -y --no-install-recommends libsqlite3-dev python3 build-essential && \
    yarn config set python /usr/bin/python3

# From here on we use the least-privileged `node` user to run the backend.
USER node

# This should create the app dir as `node`.
# If it is instead created as `root` then the `tar` command below will fail: `can't create directory 'packages/': Permission denied`.
# If this occurs, then ensure BuildKit is enabled (`DOCKER_BUILDKIT=1`) so the app dir is correctly created as `node`.
WORKDIR /app

# Copy the install dependencies from the build stage and context
COPY --from=build --chown=node:node /app/yarn.lock /app/package.json /app/packages/backend/dist/skeleton/ ./

RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \
    yarn install --frozen-lockfile --production --network-timeout 600000

# Copy the built packages from the build stage
COPY --from=build --chown=node:node /app/packages/backend/dist/bundle/ ./

# Copy any other files that we need at runtime
COPY --chown=node:node app-config.yaml ./

# This switches many Node.js dependencies to production mode.
ENV NODE_ENV production

CMD ["node", "packages/backend", "--config", "app-config.yaml"]

The Docker build command is the following, ran at the root. docker image build -t backstage .

Jonas Arcangel
  • 2,085
  • 11
  • 55
  • 85

1 Answers1

1

That RUN does not work;

RUN yarn build:backend --config ../../app-config.yaml

If index.ts is in the directory packages/backend/src, you may need to change the working directory before executing the yarn build:backend command.

But before that, I noticed two potential issues in your Dockerfile:

  1. You are running yarn install --frozen-lockfile twice in the build stage. Once before and once after copying all the files. The second one might be overwriting the packages installed by the first one.

  2. In the packages stage, you are deleting all files not named package.json. That is likely causing the error Could not resolve entry module (src/index.ts). because you are deleting index.ts before it gets to the build stage.

Given this, you might want to adjust your Dockerfile like this:

# ...
COPY --from=packages --chown=node:node /app .

# Stop cypress from downloading it is massive binary.
ENV CYPRESS_INSTALL_BINARY=0
RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \
    yarn install --frozen-lockfile --network-timeout 600000

# The command above already installs all packages, remove the line below
# RUN yarn install --frozen-lockfile

COPY --chown=node:node . .

RUN yarn tsc 

WORKDIR /app/packages/backend
RUN yarn backstage-cli build --config ../../app-config.yaml
# ...

Two final comments:

  • Your Dockerfile seems to have been adapted from an example that uses better-sqlite3 which requires native extensions to be built. If you are not using better-sqlite3 in your project, you can remove the lines related to libsqlite3-dev and better-sqlite3. If you are unsure, please check your package.json files for such dependencies.

  • The Docker build cache might be interfering with your debugging. Try running the Docker build command with --no-cache option to disable build cache:

    docker image build --no-cache -t backstage .
    

The OP Jonas Arcangel suggests in the comments:

I see that the package.json has the package build command.

Rather than continue with my own changes to the Dockerfile, I've reverted back to the original one and use yarn commmands to do it rather than my own docker build.

 "scripts": {
   "build": "backstage-cli package build",
   "build-image": "docker build ../.. -f Dockerfile --tag example-backend",
   ...
 }
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I see that the package.json has the package build command. Rather than continue with my own changes to the Dockerfile, I've reverted back to the original one and use yarn commmands to do it rather than my own docker build. – Jonas Arcangel Jul 17 '23 at 10:16
  • @JonasArcangel Good call. What yarn commands did you use? – VonC Jul 17 '23 at 11:27
  • yarn build-image. https://github.com/backstage/demo/blob/2fa1269d9352258055f20e588ba2b175599f02ee/packages/backend/package.json#L12 – Jonas Arcangel Jul 17 '23 at 22:36
  • @JonasArcangel Thank you for the update. I have included your comments in the answer for more visibility. – VonC Jul 18 '23 at 06:12