Docker WORKDIR path is added to relative path

Viewed 1321

I have the trouble that the following DOCKERFILE ends up in a exception, where it cant find /src/webui/tail -f /dev/null and thats right, because I wanted to execute only tail -f /dev/null.

docker build is working, docker run is failing!

How can I avoid that the WORKDIR path is added to the tail command?

DOCKERFILE:

FROM node:12.17.0-alpine
WORKDIR /src/webui
RUN apk update && apk add bash
CMD ["tail -f /dev/null"]

Exception:

> docker run test
internal/modules/cjs/loader.js:969
  throw err;
  ^

Error: Cannot find module '/src/webui/tail -f /dev/null'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:966:15)
    at Function.Module._load (internal/modules/cjs/loader.js:842:27)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

System Information:

  • Docker Desktop (Windows 10 Pro)
  • Docker version 19.03.8, build afacb8b
3 Answers

When you give CMD (or RUN or ENTRYPOINT) in the JSON-array form, you're responsible for manually breaking up the command into "words". That is, you're running the equivalent of the quoted shell command

'tail -f /dev/null'

and the whole thing gets interpreted as one "word" -- the spaces and options are taken as part of the command name to look up in $PATH.

The most straightforward workaround to this is to remove the quoting and just use a bare string as CMD.

Note that the container you're building doesn't actually do anything: it doesn't include any application source code and the command you're providing intentionally does nothing forever. Aside from one running container with an idle process, you get the same effect by just not running the container at all. You typically want to copy your application code in and set CMD to actually run it:

FROM node:12.17.0-alpine
WORKDIR /src/webui
COPY package.json yarn.lock ./
RUN yarn install
COPY . ./
CMD ["yarn", "start"]
# Also works:  CMD yarn start
# Won't work:  CMD ["yarn start"]

The correct Dockerfile:

FROM node:12.17.0-alpine
WORKDIR /src/webui
RUN apk update && apk add bash
CMD ["tail", "-f", "/dev/null"]

So the difference is that this:

CMD ["tail -f /dev/null"]

needs to be:

CMD ["tail", "-f", "/dev/null"]

You can read more about CMD in the official Docker docs.

CMD will append after ENTRYPOINT

Since node:12.17.0-alpine have default ENTRYPONINT node

Your dockerfile will becomes

node tail -f /dev/null

option1

Override ENTRYPOINT in build time

ENTRYPOINT tail -f /dev/null

option2

Override ENTRYPOINT in run time

docker run --entrypoint sh my-image
Related