docker command

本文解释在DockerfileCMDENTRYPOINT的区别 以及在使用是与命令行参数的交互情况

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

在单一指令的情况下 不同格式的等价效果

  • 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

CMD

CMD 会多一个格式 就是完全作为 ENTRYPOINT 的参数(但其实没区别)

# (as default parameters to ENTRYPOINT)
CMD ["param1","param2"]
1
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
$ sudo docker run hello
hello

$ sudo docker run hello world
hello
1
2
3
4
5

可以看出 shell 格式的 ENTRYPOINT 会覆盖掉命令行参数和 CMD

exec 格式

FROM alpine

ENTRYPOINT ["echo", "hello;"]
CMD [ "echo","world;" ]
1
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

CMD的参数形式

从上面的例子中 可以看出 CMD 并入 ENTRYPOINT 的方式就是将 CMD 列表中的值作为参数传递给 ENTRYPOINT 执行

官方文档open in new window

No ENTRYPOINTENTRYPOINT exec_entry p1_entryENTRYPOINT [“exec_entry”, “p1_entry”]
No CMDerror, not allowed/bin/sh -c exec_entry p1_entryexec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”]exec_cmd p1_cmd/bin/sh -c exec_entry p1_entryexec_entry p1_entry exec_cmd p1_cmd
CMD [“p1_cmd”, “p2_cmd”]p1_cmd p2_cmd/bin/sh -c exec_entry p1_entryexec_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_entryexec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

If CMD is defined from the base image, setting ENTRYPOINT will reset CMD to an empty value. In this scenario, CMD must be defined in the current image to have a value.

设置 ENTRYPOINT 会将基础镜像中的 CMD 置空(如果有) 在这种情况下 CMD 只能在当前镜像中定义