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?

2

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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.
Added same example using Dockerfile @MikeWilliamson
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).
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.
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'.

1 Comment

Docker start runs both ENTRYPOINT and CMD. If you don't specify ENTRYPOINT, it uses the default one instead (/bin/sh -c).
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/

Comments

-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

1 Comment

docker start also runs the image.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.