Dockerfile 中的 ENTRYPOINT 和 CMD 指令定义了容器的默认启动命令。但是,在运行容器时,这些指令可以被 Docker run 命令行参数覆盖。
覆盖优先级关系如下:
- 如果在运行容器时指定了
--entrypoint
选项,则将覆盖 Dockerfile 中指定的 ENTRYPOINT 命令。 - 如果在运行容器时指定了命令行参数,则将覆盖 Dockerfile 中指定的 CMD 命令。
- 如果 Dockerfile 中指定了 ENTRYPOINT 命令,但没有指定 CMD 命令,则在运行容器时,命令行参数将成为 CMD 命令。
- 如果 Dockerfile 中既没有指定 ENTRYPOINT 命令,也没有指定 CMD 命令,则在运行容器时,命令行参数将被视为完整的命令,直接执行。
例如,假设有以下 Dockerfile:
FROM ubuntu
ENTRYPOINT ["/bin/echo", "Hello,"]
CMD ["world!"]
该 Dockerfile 定义了一个以 Ubuntu 为基础镜像的容器,并将 "/bin/echo"
和 "Hello,"
作为 ENTRYPOINT 命令,将 "world!"
作为 CMD 命令。
如果运行容器时不指定任何参数,则将执行默认的 ENTRYPOINT 和 CMD 命令,输出如下:
$ docker run myimage
Hello, world!
如果在运行容器时指定了命令行参数,则将覆盖 CMD 命令,例如:
$ docker run myimage "GPT-3"
输出将变为:
Hello, GPT-3!
如果在运行容器时使用 --entrypoint
选项指定新的命令,则将覆盖 ENTRYPOINT 命令,例如:
$ docker run --entrypoint /bin/ls myimage /
输出将为容器根目录下的文件列表。
需要注意的是,如果在 Dockerfile 中同时指定了 ENTRYPOINT 和 CMD 命令,则在运行容器时可以通过命令行参数来覆盖 CMD 命令,但无法覆盖 ENTRYPOINT 命令,除非使用 --entrypoint
选项指定新的 ENTRYPOINT 命令。