0%

Dockerfile-CMD与ENTRYPOINT简记

CMD,有多个的话之后最后一个生效,作为启动时的默认命令行和用于向 ENTRYPOINT 传递参数,会被 docker run 带的命令行和参数覆盖。

ENTRYPOINT,有多个时最后一个生效,启动时执行,不会被 docker run 带的命令行和参数覆盖。

exec form 和 shell form

两者都有 exec 和 shell 两种格式的写法,如下:

1
2
3
4
# exec form
ENTRYPOINT ["executable", "param1", "param2"]
#shell form
ENTRYPOINT command param1 param2

exec 形式的写法,第一项应当是一个可执行命令。

shell 形式的写法,会按照

1
sh -c command param1 param2

来执行。

关于两种格式和 CMD 与 ENTRYPOINT 的组合情况,docker 官网给出了一个很简洁易懂的表格:

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 [“exec_cmd”, “p1_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

exec 写法如果要传入参数,比如

1
ENTRYPOINT [ "echo", "$HOME" ]

将输出

1
$HOME

因为不会执行 shell,需要参数替换的话,可以调用 shell 执行:

1
ENTRYPOINT [ "sh", "-c", "echo $HOME" ]

docker run 覆盖 CMD 命令行和参数

关于 CMD 被启动时命令行覆盖,可见下面例子,假如镜像 testcmd 的 DockerFile 如下:

1
2
3
4
FROM gcc
WORKDIR /app
COPY . /app
CMD ["/bin/echo","tian"]

如果使用:

1
docker run testcmd

将输出默认的:

1
tian

如果使用:

1
docker run testcmd echo matian

将输出:

1
matian

CMD 向 ENTRYPOINT 传参

关于 CMD 向 ENTRYPOINT 的传参,结合表格很容易明白,可见下面例子:

1
2
3
4
5
FROM gcc
WORKDIR /app
COPY . /app
CMD ["ma","tian"]
ENTRYPOINT ["/bin/echo","hello"]

执行

1
docker run testcmd

将输出

1
hello ma tian

执行

1
docker run testcmd tian ma

将输出

1
hello tian ma

ENV 参数

关于 ENV 定义的参数,见下例:

1
2
3
4
5
FROM gcc
WORKDIR /app
COPY . /app
ENV NAME=""
ENTRYPOINT ["sh","-c","echo $NAME"]

执行

1
docker run -e NAME="matian" testcmd

将输出

1
matian

要注意 -e NAME=”matian” 在命令中的位置,testcmd(镜像名)在最后。