2014-09-25 149 views
6

假设码头集装箱已经运行'码头运行',然后停止'码头停止'。 “码头启动”之后会执行“CMD”命令吗?'docker start'是否执行CMD命令?

+1

检查这个问题:CMD和入口点在Dockerfile之间的区别是什么?(http://stackoverflow.com/q/21553353/4677231)为了解大'CMD','入口点' – sEpmein 2015-03-28 13:00:43

回答

6

我相信@jripoll不正确,它似乎运行,这是第一次运行与docker rundocker start过的命令。

这里有一个简单的例子来测试:

首先创建一个shell脚本来运行名为tmp.sh

echo "hello yo!" 

然后运行:

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

,将打印hello yo!

现在再次启动它:

docker start -ia yo 

它将每次运行那个时候再次打印。

3

当你做码头工人开始,你叫api/client/start.go,这就要求:

cli.client.ContainerStart(containerID) 

这就要求engine-api/client/container_start.go

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

的码头工人守护进程API调用daemon/start.go

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

容器监视器在012中运行容器:

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

默认情况下,码头工人守护进程是这里的主管,在daemon/daemon.go

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

而且execDriver创造了daemon/execdriver/windows/exec.go命令行:

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

使用的processConfig.EntrypointandprocessConfig.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 
} 

那些ProcessConfig.Arguments被填充在daemon/container_operations_windows.go

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

,与c.Args是一个容器的参数(runtile参数或CMD

所以肯定的, 'CMD' 的命令是在'docker start'后执行。

0

如果您希望您的容器每次都运行相同的可执行文件,那么您应该考虑将ENTRYPOINTCMD结合使用。

注意:不要混淆RUNCMD。 RUN实际上运行一个命令并提交结果; CMD在构建时不执行任何操作,但指定图像的预期命令。

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