Backstage failed to start up: [Error: ENOENT: no such file or directory, scandir '/app/plugins/xxx]

481 Views Asked by At

I have a plugin named "inventory-backend". It includes Knex migrations folder, "migrations". It works fine locally.

Here, I created a Docker image, completely following Backstage Docs (https://backstage.io/docs/deployment/k8s/ and https://backstage.io/docs/deployment/docker/). Here is my Dockerfile:

FROM node:18-bookworm-slim

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 python3 g++ build-essential && \
    yarn config set python /usr/bin/python3

USER node

WORKDIR /app

ENV NODE_ENV production

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

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

COPY --chown=node:node packages/backend/dist/bundle.tar.gz app-config*.yaml ./
RUN tar xzf bundle.tar.gz && rm bundle.tar.gz

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

Next, I'm deploying Postgre and Backstage, again, in the way that docs suggest. But the pod that gets created with the deployment gets this error:

Backend failed to start up [Error: ENOENT: no such file or directory, scandir '/app/plugins/inventory-backend/migrations'] { errno: -2, code: 'ENOENT', syscall: 'scandir', path: '/app/plugins/inventory-backend/migrations' }

When I look inside the container, I don't see my "migrations" folder. So I added this line to Dockerfile:

COPY plugins/inventory-backend/migrations /app/plugins/inventory-backend/migrations

Now when I check inside the container, I see that migrations folder is there. But it gives me the same error. How can this happen?

My package.json file:

{
  "name": "root",
  "version": "1.0.0",
  "private": true,
  "engines": {
    "node": "16 || 18"
  },
  "scripts": {
    "dev": "concurrently \"yarn start\" \"yarn start-backend\"",
    "start": "yarn workspace app start",
    "start-backend": "yarn workspace backend start",
    "build:backend": "yarn workspace backend build",
    "build:all": "backstage-cli repo build --all",
    "build-image": "yarn workspace backend build-image",
    "tsc": "tsc",
    "tsc:full": "tsc --skipLibCheck false --incremental false",
    "clean": "backstage-cli repo clean",
    "test": "backstage-cli repo test",
    "test:all": "backstage-cli repo test --coverage",
    "lint": "backstage-cli repo lint --since origin/main",
    "lint:all": "backstage-cli repo lint",
    "prettier:check": "prettier --check .",
    "new": "backstage-cli new --scope internal"
  },
  "workspaces": {
    "packages": [
      "packages/*",
      "plugins/*"
    ]
  },
  "devDependencies": {
    "@backstage/cli": "^0.22.13",
    "@spotify/prettier-config": "^12.0.0",
    "concurrently": "^6.0.0",
    "lerna": "^4.0.0",
    "prettier": "^2.3.2",
    "typescript": "~5.0.0"
  },
  "resolutions": {
    "@types/react": "^17",
    "@types/react-dom": "^17"
  },
  "prettier": "@spotify/prettier-config",
  "lint-staged": {
    "*.{js,jsx,ts,tsx,mjs,cjs}": [
      "eslint --fix",
      "prettier --write"
     ],
    "*.{json,md}": [
      "prettier --write"
    ]
  },
  "dependencies": {
    "@backstage/errors": "^1.2.2",
    "@manypkg/get-packages": "^1.1.3",
    "@types/pg": "^8.10.2",
    "@types/uuid": "^9.0.3",
    "express": "^4.18.2",
    "express-promise-router": "^4.1.1",
    "node-gyp": "^9.4.0",
    "p5": "^1.7.0",
    "pg": "^8.11.3"
  }
}

And my tsconfig file:

{
  "extends": "@backstage/cli/config/tsconfig.json",
  "include": [
    "packages/*/src",
    "plugins/*/src",
    "plugins/*/dev",
    "plugins/*/migrations"
  ],
  "exclude": ["node_modules"],
  "compilerOptions": {
    "jsx": "react",
    "outDir": "dist-types",
    "rootDir": "."
  }
}

ls output of the /app directory:

app-config.production.yaml app-config.yaml node_modules package.json packages plugins yarn.lock

Here, app-config.production.yaml does not have overriding effect on app-config.yaml, as a note. Thank you.

3

There are 3 best solutions below

0
On BEST ANSWER

SOLVED: It seems that my minikube was using its own Docker runtime, not the local Docker runtime that I was using. So I changed the runtime environment to local Docker, problem solved.

If anyone has the same case, FYI.

7
On

I spent half a year integrating Backstage at my company and have created several plugins.

Make sure that the plugin has all of its dependencies and that you have also chown'd the owner to node:node.

0
On

You need to add


  "files": [
    "dist",
    "migrations"
  ]

to your package.json to make the migrations be part of your built app