Dockerfile 的 CMD 和 ENTRYPOINT 区别与联系
原创
©著作权归作者所有:来自51CTO博客作者mb63e0bfee4d9bf的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、CMD 和 ENTRYPOINT 使用方法
CMD 命令的三种用法:
The CMD instruction has three forms:
# exec 形式,这是首选形式,即官方推荐
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
# 作为 ENTRYPOINT 的参数
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
# shell 形式
CMD command param1 param2 (shell form)
ENTRYPOINT 命令的两种用法:
ENTRYPOINT has two forms:
# exec 形式,这是首选形式,即官方推荐
ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
# shell 形式
ENTRYPOINT command param1 param2 (shell form)
二、示例
1、CMD 和 ENTRYPOINT 都可以作为容器启动的运行的命令。
容器启动运行 CMD 命令
Dockerfile:
FROM alpine
CMD ["/bin/sh", "-c", "echo 'hello cmd'"] # 等价于 CMD echo "hello cmd"
制作镜像:
[root@localhost test]# docker build -t hausen1012/test .
# 构建过程....
启动容器:
[root@localhost test]# docker run hausen1012/test
hello cmd
容器启动运行 ENTRYPOINT 命令
Dockerfile:
FROM alpine
ENTRYPOINT ["/bin/sh", "-c", "echo 'hello entrypoint'"] # 等价于 ENTRYPOINT echo "hello entrypoint"
制作镜像:
[root@localhost test]# docker build -t hausen1012/test2 .
# 构建过程....
启动容器:
[root@localhost test]# docker run hausen1012/test2
hello entrypoint
结果:都能作为容器启动执行的命令。
2、多个 CMD 和 ENTRYPOINT 命令最后一条才生效
多个 CMD 命令
Dockerfile:
FROM alpine
CMD echo 111
CMD echo 222
CMD echo 333
制作镜像:
[root@localhost test]# docker build -t hausen1012/test3 .
# 构建过程....
启动容器:
[root@localhost test]# docker run hausen1012/test3
333
容器启动运行 ENTRYPOINT 命令
Dockerfile:
FROM alpine
ENTRYPOINT echo 111
ENTRYPOINT echo 222
ENTRYPOINT echo 333
制作镜像:
[root@localhost test]# docker build -t hausen1012/test4 .
# 构建过程....
启动容器:
[root@localhost test]# docker run hausen1012/test4
333
结果:同时写多个 CMD 或 ENTRYPOINT 只有最后一条生效
上面都是一样的,两个命令没有任何区别。下面讲讲区别。
3、Docker run 覆盖启动命令
容器启动时尝试覆盖 CMD 命令
Dockerfile:
FROM alpine
CMD ["/bin/sh", "-c", "echo 'hello cmd'"]
制作镜像:
[root@localhost test]# docker build -t hausen1012/test5 .
# 构建过程....
启动容器:
[root@localhost test]# docker run hausen1012/test5 echo "changed by run"
changed by run
可以看见本该输出 hello cmd,变成了 changed by run。
容器启动运行 ENTRYPOINT 命令
Dockerfile:
FROM alpine
ENTRYPOINT ["/bin/sh", "-c", "echo 'hello entrypoint'"]
制作镜像:
[root@localhost test]# docker build -t hausen1012/test6 .
# 构建过程....
启动容器:
[root@localhost test]# docker run hausen1012/test6 echo "changed by run"
hello entrypoint
可以看见,还是原来的输出。
结果:CMD 执行的启动命令可以被 Docker run 覆盖,但是 ENTRYPOINT 则不行。
4、CMD 作为 ENTRYPOINT 的参数
Dockerfile:
FROM alpine
CMD ["I am cmd"]
ENTRYPOINT ["echo"]
制作镜像:
[root@localhost test]# docker build -t hausen1012/test7 .
# 构建过程....
启动容器:
[root@localhost test]# docker run hausen1012/test7
I am cmd
[root@localhost test]# docker run hausen1012/test7 "I am run"
I am run
结果:CMD 可以作为 ENTRYPOINT 的参数,当 Docker run 传递参数时,会覆盖掉 CMD 的参数。
多个 CMD 传参时,只有最后一个 CMD 有效。
注意:
alpine 镜像里面没有 bash,即:
使用 CMD ["/bin/bash", “-c”, “echo ‘hello cmd’”] 会报错,
使用 CMD ["/bin/sh", “-c”, “echo ‘hello cmd’”] 则能正常输出。