Difference between RUN and CMD in a Dockerfile
Asked Answered
S

10

681

I'm confused about when should I use CMD vs RUN. For example, to execute bash/shell commands (i.e. ls -la) I would always use CMD or is there a situation where I would use RUN? Trying to understand the best practices about these two similar Dockerfile directives.

Samp answered 26/5, 2016 at 13:11 Comment(1)
D
1002

RUN is an image build step, the state of the container after a RUN command will be committed to the container image. A Dockerfile can have many RUN steps that layer on top of one another to build the image.

CMD is the command the container executes by default when you launch the built image. A Dockerfile will only use the final CMD defined. The CMD can be overridden when starting a container with docker run $image $other_command.

ENTRYPOINT is also closely related to CMD and can modify the way a CMD is interpreted when a container is started from an image.

Deeann answered 26/5, 2016 at 13:25 Comment(12)
you do all the RUNneeded to setup your environment, and your (only) CMD launches the process running in your container, example, for nginx, extract from github.com/nginxinc/docker-nginx/blob/… you see the line CMD ["nginx", "-g", "daemon off;"]Unreligious
"A Dockerfile can only have one CMD" - not technically true, but effectively all but one will be ignored. See the answer of GingerBeer.Sievers
"A Dockerfile will only use the final CMD defined"? actually, the final CMD defined will be used in launching image as a container, right?Faddist
Yes @paulcheung the final command in the dockerfile is written to the image and is the command the container executes by default when you launch the built image.Deeann
"A Dockerfile will only use the final CMD defined." -- I just wasted the past hour because I did not realize this. Why on earth wouldn't they at least give you a warning if they are going to ignore these?Autolycus
In this case why is my container running as if there is a CMD in the Dockerfile? There is no CMD only RUN and yet it runs helm when I try docker run.Dykes
None of these answers are explaining the actual difference in effect. If both apply to the same image than they are both identical commands, unless one does something different. Do they?Cola
@Cola Yes they are different. I'm not sure how to state the effects differently though. Maybe think of it in terms of images you use from a container registry. RUN commands execute at build time (usually remote) before the image is uploaded. The CMD is the process your local container runtime executes after you have retrieved the image.Deeann
" the state of the container after a RUN command will be committed to the container image" What does this mean?Lazare
Would writing a command as a value of the last RUN entry result in an equivalent behaviour of writing the same command in the sole CMD entry?Lazare
@MehdiCharife That's not guaranteed, as a CMD environment could be very different to the image build RUN environment (volumes, env, build args) that could affect the output.Deeann
And any file system changes not being committed after aCMDDeeann
Z
310

RUN - command triggers while we build the docker image.

CMD - command triggers while we launch the created docker image.

Zeeland answered 17/7, 2017 at 6:56 Comment(1)
And the difference is? What we need to know, as the OP asked, is how to know when to use one and not the other. These factoids leave that an open question. Practical effects are what engineers need to know.Cola
L
129

I found the Docker RUN vs CMD vs ENTRYPOINT article very helpful to understand the difference between them:

RUN - RUN instruction allows you to install your application and packages required for it. It executes any commands on top of the current image and creates a new layer by committing the results. Often you will find multiple RUN instructions in a Dockerfile.

CMD - CMD instruction allows you to set a default command, which will be executed only when you run container without specifying a command. If Docker container runs with a command, the default command will be ignored. If Dockerfile has more than one CMD instruction, all but last
CMD instructions are ignored.

Lavernelaverock answered 1/1, 2017 at 13:14 Comment(2)
I'm confused here: I thought dependencies will be actually installed only after container is up. In the docker build stage, we haven't started the container, then how docker is able to pull down the dependencies into the result container?Apposition
Thank you for being the only person who tried to answer the OP question. I don't understand why so many people feel the need to create noise when what we need is valuable information.Cola
S
38

The existing answers cover most of what anyone looking at this question would need. So I'll just cover some niche areas for CMD and RUN.

CMD: Duplicates are Allowed but Wasteful

GingerBeer makes an important point: you won't get any errors if you put in more than one CMD - but it's wasteful to do so. I'd like to elaborate with an example:

FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"

If you build this into an image and run a container in this image, then as GingerBeer states, only the last CMD will be heeded. So the output of that container will be:

Executing CMD 2

The way I think of it is that "CMD" is setting a single global variable for the entire image that is being built, so successive "CMD" statements simply overwrite any previous writes to that global variable, and in the final image that's built the last one to write wins. Since a Dockerfile executes in order from top to bottom, we know that the bottom-most CMD is the one gets this final "write" (metaphorically speaking).

RUN: Commands May not Execute if Images are Cached

A subtle point to notice about RUN is that it's treated as a pure function even if there are side-effects, and is thus cached. What this means is that if RUN had some side effects that don't change the resultant image, and that image has already been cached, the RUN won't be executed again and so the side effects won't happen on subsequent builds. For example, take this Dockerfile:

FROM busybox
RUN echo "Just echo while you work"

First time you run it, you'll get output such as this, with different alphanumeric IDs:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest

Notice that the echo statement was executed in the above. Second time you run it, it uses the cache, and you won't see any echo in the output of the build:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Using cache
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
Sievers answered 19/4, 2020 at 10:45 Comment(1)
I've bumped into the caching landmine you talked about; created much headscratching before I realized how things were broken. I had to use docker-compose build --no-cache to get around the issue. Great answer bud; upvote!Vulgus
U
29

RUN - Install Python , your container now has python burnt into its image
CMD - python hello.py , run your favourite script

Unshakable answered 20/2, 2018 at 12:10 Comment(3)
CMD - Install Python, my container now doest not hast python burnt into its image?Frankly
RUN will create an image layer of python , CMD will simply execute the command not create the imageUnshakable
CMD does not execute anything at build time, but specifies the intended command for the image. -DocMyel
L
22

Note: Don’t confuse RUN with CMD. RUN actually runs a command and commits the result; CMD does not execute anything at build time, but specifies the intended command for the image.

from docker file reference

https://docs.docker.com/engine/reference/builder/#cmd

Lorant answered 1/5, 2017 at 9:59 Comment(1)
So much confusion could be avoided if this were the accepted answer. This is the only thing an engineer really needs to know.Cola
I
16

RUN Command: RUN command will basically, execute the default command, when we are building the image. It also will commit the image changes for next step.

There can be more than 1 RUN command, to aid in process of building a new image.

CMD Command: CMD commands will just set the default command for the new container. This will not be executed at build time.

If a docker file has more than 1 CMD commands then all of them are ignored except the last one. As this command will not execute anything but just set the default command.

Intercurrent answered 29/10, 2018 at 10:15 Comment(0)
K
15

RUN: Can be many, and it is used in build process, e.g. install multiple libraries

CMD: Can only have 1, which is your execute start point (e.g. ["npm", "start"], ["node", "app.js"])

Katey answered 23/1, 2020 at 23:5 Comment(0)
H
13

There has been enough answers on RUN and CMD. I just want to add a few words on ENTRYPOINT. CMD arguments can be overwritten by command line arguments, while ENTRYPOINT arguments are always used.

This article is a good source of information.

Horseback answered 21/11, 2019 at 2:39 Comment(1)
That link is awesome!Burchette
F
-3

You should use RUN because it is better for running files on the computer, plus it is easier to use.

Furtive answered 21/8, 2023 at 0:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.