英文:
Backstage Docker build error in yarn step
问题
以下是翻译好的部分:
我按照 https://backstage.io/docs/deployment/docker/#multi-stage-build 中的步骤创建了一个 Dockerfile。
当在根目录运行 Dockerfile 命令 "docker image build -t backstage ." 时,我收到了下面的错误。我确认在 packages\backend\src 文件夹中存在 index.ts 文件。
错误信息如下:
> [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 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.
Dockerfile 如下,并位于根目录。
# 阶段1 - 创建yarn安装骨架层
FROM node:16-bullseye-slim AS packages
WORKDIR /app
COPY package.json yarn.lock ./
COPY packages packages
# 如果没有内部插件,请注释掉以下行
# 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 {} +
# 阶段2 - 安装依赖并构建包
FROM node:16-bullseye-slim AS build
# 安装sqlite3依赖
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 .
# 停止cypress下载其庞大的二进制文件。
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
# ---- 失败在这里 ----
#RUN yarn build:backend --config ../../app-config.yaml
# --------------------
#RUN yarn --cwd packages/backend build
# 如果还没有迁移到包角色,请改用以下命令:
#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
# 阶段3 - 构建实际的后端镜像并安装生产依赖项
FROM node:16-bullseye-slim
# 安装sqlite3依赖。如果镜像中不使用sqlite3,可以跳过此步骤,此时还应将better-sqlite3移动到package.json中的“devDependencies”中。
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
# 从此处开始,我们使用权限最低的“node”用户来运行后端。
USER node
# 这应该将app目录创建为“node”。
# 如果它以“root”创建,那么下面的“tar”命令将失败:“can't create directory 'packages/': Permission denied”。
# 如果发生这种情况,请确保启用了BuildKit(DOCKER_BUILDKIT=1),以便正确创建app目录为“node”。
WORKDIR /app
# 从构建阶段和上下文中复制安装依赖项
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 --from=build --chown=node:node /app/packages/backend/dist/bundle/ ./
# 复制在运行时需要的任何其他文件
COPY --chown=node:node app-config.yaml ./
# 这会将许多Node.js依赖项切换到生产模式。
ENV NODE_ENV production
CMD ["node", "packages/backend", "--config", "app-config.yaml"]
Docker构建命令如下,位于根目录。
docker image build -t backstage .
英文:
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 .
答案1
得分: 1
这个RUN
命令不起作用:
RUN yarn build:backend --config ../../app-config.yaml
如果index.ts
位于packages/backend/src
目录中,你可能需要在执行yarn build:backend
命令之前更改工作目录。
但在此之前,我注意到你的Dockerfile中存在两个潜在问题:
-
你在构建阶段两次运行了
yarn install --frozen-lockfile
命令。一次在复制所有文件之前,一次在复制所有文件之后。第二次运行可能会覆盖第一次安装的包。 -
在
packages
阶段,你删除了所有不是package.json
命名的文件。这很可能导致错误Could not resolve entry module (src/index.ts)
,因为你在进入build
阶段之前删除了index.ts
文件。
鉴于此,你可以像这样调整你的Dockerfile:
# ...
COPY --from=packages --chown=node:node /app .
# 阻止Cypress下载大型二进制文件。
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
# 上面的命令已经安装了所有的包,删除下面这行
# 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
# ...
最后两点建议:
-
你的Dockerfile似乎是从一个使用了
better-sqlite3
的示例中改编而来的,而better-sqlite3
需要构建本机扩展。如果你的项目中没有使用better-sqlite3
,可以删除与libsqlite3-dev
和better-sqlite3
相关的行。如果不确定,请检查你的package.json
文件以查找这样的依赖项。 -
Docker构建缓存可能会影响你的调试。尝试使用
--no-cache
选项运行Docker构建命令以禁用构建缓存:
docker image build --no-cache -t backstage .
OP Jonas Arcangel 在评论中建议:
> 我看到package.json
中有包构建命令。
>
> 与其继续对Dockerfile
进行更改,我已恢复到原始状态,并使用yarn命令执行构建而不是自己的Docker构建。
>
> Dockerfile > "scripts": { > "build": "backstage-cli package build", > "build-image": "docker build ../.. -f Dockerfile --tag example-backend", > ... > } >
英文:
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:
-
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. -
In the
packages
stage, you are deleting all files not namedpackage.json
. That is likely causing the errorCould not resolve entry module (src/index.ts).
because you are deletingindex.ts
before it gets to thebuild
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 usingbetter-sqlite3
in your project, you can remove the lines related tolibsqlite3-dev
andbetter-sqlite3
. If you are unsure, please check yourpackage.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.
>
> Dockerflie
> "scripts": {
> "build": "backstage-cli package build",
> "build-image": "docker build ../.. -f Dockerfile --tag example-backend",
> ...
> }
>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论