Search code examples
dockerdockerfiledocker-containerdocker-builddocker-run

Is there a real use case of declaring more than one CMD in the dockerfile?


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?


Solution

  • 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.)