Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does 'docker start' execute the CMD command?

Tags:

docker

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'?

like image 685
Julien Christin Avatar asked Sep 25 '14 07:09

Julien Christin


2 Answers

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.

like image 87
Travis Reeder Avatar answered Oct 17 '22 07:10

Travis Reeder


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'.

like image 7
VonC Avatar answered Oct 17 '22 06:10

VonC