GoogleContainerTools / distroless

🥑 Language focused docker images, minus the operating system.
Apache License 2.0
19.02k stars 1.16k forks source link

Using gcr.io/distroless/nodejs20-debian12 image but node and npm commands not found #1637

Open semihural-tomtom opened 3 months ago

semihural-tomtom commented 3 months ago

I'm trying to run my Node.js application using thegcr.io/distroless/nodejs20-debian12:debug image. However, when I execute my application, I get the following error:

I am using the npx command in my docker-compose file, but it seems like node and npm are not installed in the container. Why are the node and npm commands not found in the gcr.io/distroless/nodejs20-debian12:debug image?

How can I run npx commands using a distroless Node.js image?

docker logs -f 33ab810a0a37

node:internal/modules/cjs/loader:1148
  throw err;
  ^

Error: Cannot find module '/app/npx'
    at Module._resolveFilename (node:internal/modules/cjs/loader:1145:15)
    at Module._load (node:internal/modules/cjs/loader:986:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12)
    at node:internal/main/run_main_module:28:49 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

Node.js v20.16.0

It seems like the Node.js runtime is not available. Here are the details when I run the container interactively:

docker run --entrypoint=sh -ti wt/collector:v1

WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
/app # cat /etc/*release*
PRETTY_NAME="Distroless"
NAME="Debian GNU/Linux"
ID="debian"
VERSION_ID="12"
VERSION="Debian GNU/Linux 12 (bookworm)"
HOME_URL="https://github.com/GoogleContainerTools/distroless"
SUPPORT_URL="https://github.com/GoogleContainerTools/distroless/blob/master/README.md"
BUG_REPORT_URL="https://github.com/GoogleContainerTools/distroless/issues/new"
/app # node -v
sh: node: not found
/app # npm -v
sh: npm: not found
/app #
loosebazooka commented 3 months ago

We intentionally don't include npx: see https://github.com/GoogleContainerTools/distroless/commit/fdd0b4807748299a73305fe35363a429d6ce650f for removal.

node should be available, but maybe not on the path in debug. Try running it directly /nodejs/bin/node

semihural-tomtom commented 3 months ago

@loosebazooka is there any way to install this manually?

loosebazooka commented 2 months ago

you could drop it in the container using a build of some kind. Would npm exec not work for you? I don't know enough about npm.

omBratteng commented 1 week ago

sh: node: not found

You're getting this error because the node binary is at /nodejs/bin/node and not in the PATH

npx and npm are removed as @loosebazooka mentioned, as they're package managers they're not bundled with distroless.

If you still want to have npm/ npx in your image, you can just add npm as a dependency in package.json.

Take this example, it'll install npm into local node_modules in app directory and copy it over to the final stage, and it adds /nodejs/bin to the PATH

FROM node:20-bookworm-slim AS builder
WORKDIR /app
RUN npm install --save npm

FROM gcr.io/distroless/nodejs20-debian12:debug
WORKDIR /app
ENV PATH /nodejs/bin:$PATH

COPY --from=builder /app /app

Then run it like this

❯ docker run --rm -it --entrypoint sh distroless-node-with-npm          
/app # node -v
v20.18.0
/app # node node_modules/.bin/npm -v
10.9.0
/app # node node_modules/.bin/npx -v
10.9.0
omBratteng commented 1 week ago

Though, should note that it doesn't work flawlessly, as it looks like the child process node functions expects to find sh at /bin/sh (by default)