2014-09-25 146 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/