1

According to the doc:

There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect.

Why would one list more than one CMD instruction? I don't really understand this guideline. Is this like a "hack" because they are not/can not do validation of the docker file to complaint that more than 1 CMD instructions are defined or is this a real use case? I.e there is some case that we can have more than 1 CMD defined but we are ok if only the last is executed (then why were the previous defined)?
Could someone please shed some light on this?

Jim
  • 3,845
  • 3
  • 22
  • 47

1 Answers1

3

A Dockerfile is more like a shell script than a compiled program. Docker reads each line, does the thing described in that line, and creates a new layer.

A setup like this is very reasonable:

# I am "node", a node.js base image:
FROM ubuntu:18.04
RUN apt-get blah blah install nodejs
# By default on this base image just run "node"
CMD ["node"]
# I am an application-specific image based on node.js
FROM node
COPY ...
# Override that default CMD
CMD ["node", "./app.js"]

In this setup there are two CMD layers in the final image, and that's okay.

I don't immediately see a feature request to this effect in https://github.com/moby/moby/issues but, were I a Docker author, this seems like a reasonable enough "warning" type message and it probably isn't that hard to write up a pull request for it. (Keep a flag that remembers if you've seen a CMD; if you see a CMD step, warn if the flag is set, and set it if not; if you see a FROM step, reset the flag.)

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • How would this sequence change if in your specific example, instead of `CMD` was an `ENTRYPOINT`? Would the build break in the `application-specific image based on node.js`? – Jim Jan 20 '19 at 19:54
  • Same thing is true for `ENTRYPOINT`; but also note the special rule that [resetting `ENTRYPOINT` also resets `CMD`](https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact). (I tend to prefer `CMD` to `ENTRYPOINT` for the routine "set the thing this container does" setting.) – David Maze Jan 20 '19 at 19:57
  • Where? There's a pretty clear statement (mirroring this question) that [only the last `ENTRYPOINT` has an effect](https://docs.docker.com/engine/reference/builder/#entrypoint) and there's a specific [`docker run --entrypoint` option](https://docs.docker.com/engine/reference/run/#entrypoint-default-command-to-execute-at-runtime). – David Maze Jan 20 '19 at 22:14