Does 'docker start' execute the CMD command?
Asked Answered
R

4

23

Let's say a docker container has been run with docker run and then stopped with docker stop. Will the CMD command be executed after a docker start?

Relax answered 25/9, 2014 at 7:26 Comment(2)
Check this question: What is the difference between CMD and ENTRYPOINT in a Dockerfile? Great for understanding CMD,ENTRYPOINTHarrietharriett
Might be helpful: chat.stackoverflow.com/transcript/76919Viveca
O
18

I believe @jripoll is incorrect, it appears to run the command that was first run with docker run on docker start too.

Here's a simple example to test:

First create a shell script to run called tmp.sh:

echo "hello yo!"

Then run:

docker run --name yo -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp ubuntu sh tmp.sh 

That will print hello yo!.

Now start it again:

docker start -ia yo

It will print it again every time you run that.

Same thing with Dockerfile

Save this to Dockerfile:

FROM alpine

CMD ["echo", "hello yo!"]

Then build it and run it:

docker build -t hi .
docker run -i --name hi hi

You'll see "hello yo!" output. Start it again:

docker start -i hi

And you'll see the same output.

Oppidan answered 24/10, 2014 at 0:6 Comment(4)
I think you are correct, but that example does not explain the OP's question. In your case echo "hello yo!" will immediately complete, and therefore stop itself. The OP was asking what happens when you stop a container "mid-stream" with the docker stop command. Think of a web server that you stop with docker stop. I think it does exactly what you are saying, @Travis... it restarts the CMD or ENTRYPOINT. But I do want to test this myself to see. I had the same question.Dinodinoflagellate
Added same example using Dockerfile @MikeWilliamsonOppidan
Thanks, @Travis. In this case, aren't you again just running it twice (the docker run completes, then the docker start runs)? Again, I thought the OP was asking what docker start and docker stop do when mid-stream in running the container code. For instance, if there are 300 lines of source code and you stop it 150 lines into that code, what does start do? I am 99% sure it does as you are saying: it starts from the very beginning again and will operate exactly the same as the first pass through (unless any connected volumes have changed, etc).Dinodinoflagellate
I don't know how you'd stop it a few a hundred lines into your code, I'm assuming the OP was talking about some long running daemon like an HTTP server. But regardless, it appears the command will run again. The big difference between run and start is that run creates a new container, start uses an existing one.Oppidan
W
8

When you do a docker start, you call api/client/start.go, which calls:

 cli.client.ContainerStart(containerID)

That calls engine-api/client/container_start.go:

cli.post("/containers/"+containerID+"/start", nil, nil, nil)

The docker daemon process that API call in daemon/start.go:

container.StartMonitor(daemon, container.HostConfig.RestartPolicy)

The container monitor does run the container in container/monitor.go:

m.supervisor.Run(m.container, pipes, m.callback)

By default, the docker daemon is the supervisor here, in daemon/daemon.go:

daemon.execDriver.Run(c.Command, pipes, hooks)

And the execDriver creates the command line in daemon/execdriver/windows/exec.go:

createProcessParms.CommandLine, err = createCommandLine(processConfig, false)

That uses the processConfig.Entrypoint and processConfig.Arguments in daemon/execdriver/windows/commandlinebuilder.go:

// Build the command line of the process
commandLine = processConfig.Entrypoint
logrus.Debugf("Entrypoint: %s", processConfig.Entrypoint)
for _, arg := range processConfig.Arguments {
    logrus.Debugf("appending %s", arg)
    if !alreadyEscaped {
        arg = syscall.EscapeArg(arg)
    }
    commandLine += " " + arg
}

Those ProcessConfig.Arguments are populated in daemon/container_operations_windows.go:

processConfig := execdriver.ProcessConfig{
    CommonProcessConfig: execdriver.CommonProcessConfig{
        Entrypoint: c.Path,
        Arguments:  c.Args,
        Tty:        c.Config.Tty,
    },

, with c.Args being the arguments of a Container (runtile parameters or CMD)

So yes, the 'CMD' commands are executed after a 'docker start'.

Wrier answered 19/2, 2016 at 16:58 Comment(1)
Docker start runs both ENTRYPOINT and CMD. If you don't specify ENTRYPOINT, it uses the default one instead (/bin/sh -c).Marchellemarcher
K
0

If you would like your container to run the same executable every time, then you should consider using ENTRYPOINT in combination with CMD.

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.

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

Kumamoto answered 19/2, 2016 at 17:11 Comment(0)
C
-2

No, the CMD command only executed when you execute 'docker run' to run a container based in a image.

In the documentation: When used in the shell or exec formats, the CMD instruction sets the command to be executed when running the image.

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

Concordant answered 25/9, 2014 at 7:58 Comment(1)
docker start also runs the image.Busby

© 2022 - 2024 — McMap. All rights reserved.