<p>TL;DR: <code>RUN</code> performs the step during the image build, <code>CMD</code> is the default command when you start a container. If you define <code>CMD</code> and then start your container with a different command (e.g. <code>docker run $my_image /bin/bash</code>), you'll never see it run since you replaced your <code>chmod</code> command with an empty <code>/bin/bash</code> command.</p>

<hr>

<p>The detailed explanation:</p>

<p>The <strong><code>RUN</code></strong> command creates a temporary container based off of the previous step of the build, executes your selected command, and when the command returns it captures the filesystem changes as a new layer of your image. Run is the equivalent of doing a <code>docker run</code> + <code>docker commit</code> to generate your image, but with a reproducible process.</p>

<p>The <strong><code>CMD</code></strong> command replaces the current value of the image metadata for the <code>command</code> value that you can see when you inspect the image. You can only have one value for <code>CMD</code> for your image. You can also easily override the value of the image command by passing any string after the image name, e.g. <code>docker run busybox echo hello</code> replaces the default <code>/bin/sh</code> command with an <code>echo hello</code> command for that specific container.</p>

<p>There's also <strong><code>ENTRYPOINT</code></strong> which defines the entrypoint for your image. When you define an entrypoint, any value for <code>CMD</code> gets passed as arguments to the entrypoint when starting your container (a container is only started with a single process as pid 1 and exits when that process exits).</p>

<hr>

<p><strong>Shell vs Exec syntax:</strong> Note that each of these accepts a command to run in two forms, the shell/string form, and the exec/json form. The shell form is anything that isn't a json list, and the result command is run as <code>/bin/sh -c "$your_string_here"</code>. A shell is useful for IO redirection, chaining commands, and variable expansion. But a shell will also intercept signals which can cause issues when the container is stopped. The exec form runs your command directly in the OS without a shell, which is better for signals, but lacking all the other shell features. When you chain an entrypoint and cmd together, you almost always want the exec syntax since <code>/bin/sh -c</code> only accepts one argument. It's common to run a shell script but have the last command run be an <code>exec</code> which replaces the shell. E.g. a common entrypoint structure is:</p>

<p>Dockerfile:</p>

<pre><code>ENTRYPOINT ["/entrypoint.sh"]
CMD ["server", "arg1", "arg2"]
</code></pre>

<p>entrypoint.sh:</p>

<pre><code>#!/bin/sh
# ... steps to setup the host, make configs, fix permissions, copy files, etc ...
# ...
# now run the value of CMD, replacing this shell as pid 1:
exec "$@"
</code></pre>

CC BY-SA 4.0
2019-06-06T00:57:07.153Z
2019-06-06T01:02:11.893Z
2019-06-06T01:02:11.893Z
BMitch
<p>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. </p>

<p><a href="https://docs.docker.com/engine/reference/builder/#cmd" rel="nofollow noreferrer">reference</a></p>

CC BY-SA 4.0
2019-06-04T17:52:23.137Z
2019-06-04T17:52:23.137Z
Jack lee
<p>I am going to change my permission of files to <code>600</code>. The following command works perfectly.</p>

<pre><code>RUN /bin/bash -c 'chmod 600 /root/.ssh/config'
</code></pre>

<p>But this one failed</p>

<pre><code>CMD /bin/bash -c 'chmod 600 /root/.ssh/config'
</code></pre>

<p>In the beginning, I thought the shell environment isn't <code>bash</code> so caused the error. However, adding <code>bin/bash</code> didn't solve the issue.</p>

<dockerfile>
What is the difference between RUN and CMD in a Dockerfile?
rj487
# What is the difference between RUN and CMD in a Dockerfile?

(Asked by: username_0 on 2019-06-04)

I am going to change my permission of files to 600. The following command works perfectly.
RUN /bin/bash -c 'chmod 600 /root/.ssh/config'

But this one failed
CMD /bin/bash -c 'chmod 600 /root/.ssh/config'

In the beginning, I thought the shell environment isn't bash so caused the error. However, adding bin/bash didn't solve the issue.

**Tags:** dockerfile


---

## 2 answers

### Answer by username_2 on 2019-06-04. Score: 3 | Accepted answer

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.

[reference](https://docs.docker.com/engine/reference/builder/#cmd)


---

### Answer by username_1 on 2019-06-06. Score: 3

TL;DR: RUN performs the step during the image build, CMD is the default command when you start a container. If you define CMD and then start your container with a different command (e.g. docker run $my_image /bin/bash), you'll never see it run since you replaced your chmod command with an empty /bin/bash command.

The detailed explanation:
The RUN command creates a temporary container based off of the previous step of the build, executes your selected command, and when the command returns it captures the filesystem changes as a new layer of your image. Run is the equivalent of doing a docker run + docker commit to generate your image, but with a reproducible process.
The CMD command replaces the current value of the image metadata for the command value that you can see when you inspect the image. You can only have one value for CMD for your image. You can also easily override the value of the image command by passing any string after the image name, e.g. docker run busybox echo hello replaces the default /bin/sh command with an echo hello command for that specific container.
There's also ENTRYPOINT which defines the entrypoint for your image. When you define an entrypoint, any value for CMD gets passed as arguments to the entrypoint when starting your container (a container is only started with a single process as pid 1 and exits when that process exits).

Shell vs Exec syntax: Note that each of these accepts a command to run in two forms, the shell/string form, and the exec/json form. The shell form is anything that isn't a json list, and the result command is run as /bin/sh -c "$your_string_here". A shell is useful for IO redirection, chaining commands, and variable expansion. But a shell will also intercept signals which can cause issues when the container is stopped. The exec form runs your command directly in the OS without a shell, which is better for signals, but lacking all the other shell features. When you chain an entrypoint and cmd together, you almost always want the exec syntax since /bin/sh -c only accepts one argument. It's common to run a shell script but have the last command run be an exec which replaces the shell. E.g. a common entrypoint structure is:
Dockerfile:
ENTRYPOINT ["/entrypoint.sh"]
CMD ["server", "arg1", "arg2"]

entrypoint.sh:
#!/bin/sh
# ... steps to setup the host, make configs, fix permissions, copy files, etc ...
# ...
# now run the value of CMD, replacing this shell as pid 1:
exec "$@"


---

