docker command
本文解释在
Dockerfile中CMD和ENTRYPOINT的区别 以及在使用是与命令行参数的交互情况
CMD/ENTRYPOINT 的两种格式
# exec 格式
# 该格式下 Dockerfile 命令的值为 JSON数组
CMD ["cmd","param"]
ENTRYPOINT ["cmd","param"]
# shell 格式
CMD cmd param
ENTRYPOINT cmd param
1
2
3
4
5
6
7
2
3
4
5
6
7
在单一指令的情况下 不同格式的等价效果
- exec 格式:
cmd param - shell 格式:
/bin/sh -c cmd param
ENTRYPOINT
`ENTRYPOINT`的注意事项
ENTRYPOINT 的 shell 格式会覆盖 CMD 和 run 时的命令行参数
Dockerfile 中 最后一个 ENTRYPOINT 才有效(对于子镜像 这条依然成立)
ENTRYPOINT shell 格式有等价的 exec 格式
# 下面两种格式等价
ENTRYPOINT ["/bin/sh","-c","cmd","param"]
ENTRYPOINT cmd param
1
2
3
2
3
CMD
CMD 会多一个格式 就是完全作为 ENTRYPOINT 的参数(但其实没区别)
# (as default parameters to ENTRYPOINT)
CMD ["param1","param2"]
1
2
2
运行容器
docker run 时的命令行参数会覆盖 CMD
docker run --entrypoint 的参数可以覆盖 ENTRYPOINT
示例
sudo docker build -t hello .
将镜像命令为 hello
shell 格式
FROM alpine
ENTRYPOINT echo hello
CMD [ "echo","world;" ]
1
2
3
4
2
3
4
$ sudo docker run hello
hello
$ sudo docker run hello world
hello
1
2
3
4
5
2
3
4
5
可以看出 shell 格式的 ENTRYPOINT 会覆盖掉命令行参数和 CMD
exec 格式
FROM alpine
ENTRYPOINT ["echo", "hello;"]
CMD [ "echo","world;" ]
1
2
3
4
2
3
4
# echo "hello; echo world"
$ sudo docker run hello
hello; echo world;
# echo "hello; world"
$ sudo docker run hello world
hello; world
# echo "world"
$ sudo docker run --entrypoint echo hello world
world
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
CMD的参数形式
从上面的例子中 可以看出 CMD 并入 ENTRYPOINT 的方式就是将 CMD 列表中的值作为参数传递给 ENTRYPOINT 执行
官方文档
| No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“exec_entry”, “p1_entry”] | |
|---|---|---|---|
| No CMD | error, not allowed | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry |
| CMD [“exec_cmd”, “p1_cmd”] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry exec_cmd p1_cmd |
| CMD [“p1_cmd”, “p2_cmd”] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry p1_cmd p2_cmd |
| CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
If
CMDis defined from the base image, settingENTRYPOINTwill resetCMDto an empty value. In this scenario,CMDmust be defined in the current image to have a value.
设置
ENTRYPOINT会将基础镜像中的CMD置空(如果有) 在这种情况下CMD只能在当前镜像中定义