目录
CMD指令和ENTRYPOINT指令的作用都是为镜像指定容器启动后的命令。每个容器都会有一个 pid 为 1 的进程,如果COMMAND 为 /bin/bash, 说明这个容器的初始进程就是 bash 进程。
当开发人员执行docker exec -it xxxx /bin/bash 能进入容器打命令,其实就是通过伪终端(-it)打开并进入到 bash进程了。如果容器没有开启这个进程,那就直接使用sh(docker exec -it xxxx sh)。
CMD
支持三种格式
CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。
例子:
创建一个名字为startup的shell脚本:
#!/bin/bash
echo "in startup, args: $@"
-----------------------------------------------------
FROM ubuntu:14.04
MAINTAINER lienhua34@xxx.com
ADD startup /opt
RUN chmod a+x /opt/startup
CMD ["/opt/startup"]
-----------------------------------------------------
xx@test$ sudo docker run -ti --rm=true test
in startup, args:
xx@test$ sudo docker run -ti --rm=true test /bin/bash -c 'echo Hello'
Hello
ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2(shell中执行)。
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。
创建一个名字为startup的shell脚本:
#!/bin/bash
echo "in startup, args: $@"
-----------------------------------------------------
FROM ubuntu:14.04
MAINTAINER lienhua34@xxx.com
ADD startup /opt
RUN chmod a+x /opt/startup
ENTRYPOINT [“/opt/startup”]
-----------------------------------------------------
lienhua34@test$ sudo docker run -ti --rm=true test
in startup, args:
lienhua34@test$ sudo docker run -ti --rm=true test /bin/bash -c 'echo Hello'
in startup, args: /bin/bash -c echo Hello
通过上面的运行结果可以看出,docker run命令指定的容器运行命令不能覆盖Dockerfile文件中ENTRYPOINT指令指定的命令,反而被当做参数传递给ENTRYPOINT指令指定的命令。
总结
在 Dockerfile 中, 应该至少指定一个 CMD 和 ENTRYPOINT;
将 Docker 当作可执行程序时, 应该使用 ENTRYPOINT 进行配置;
CMD 可以用作 ENTRYPOINT 默认参数, 或者用作 Docker 的默认命令;
CMD 可以被 docker run 传入的参数覆盖;
docker run 传入的参数会附加到 ENTRYPOINT 之后, 前提是使用了 exec 格式 。