参考 https://www.cnblogs.com/CloudMan6/p/6875834.html
RUN CMD ENTRYPOINT 这三个 Dockerfile 指令看上去很类似, 很容易混淆.
简单的说:
RUN 执行命令并创建新的镜像层, 经常用于安装软件
CMD 设置容器启动后默认执行的命令机器参数, 但 CMD 能够被 docker run 后面跟的命令行参数替换
ENTRYPOINT 配置容器启动时运行的命令
shell 和 exex 格式
有 shell 和 exec 两种方式可以指定 RUN CMD ENTRYPOINT 要运行的命令, 两者在使用上有细微的区别
shell 格式:
<instruction> <command>
例如:
- RUN apt-get install -y python3
- CMD echo "Hello world"
- ENTRYPOINT echo "Hello world"
当指令执行时, shell 格式底层会调用 /bin/sh -c <command>
- root@docker-lab:~/017# cat Dockerfile
- FROM busybox
- ENV name www1707
- ENTRYPOINT echo "Hello $name"
- root@docker-lab:~/017# docker build -t test017 .
- Sending build context to Docker daemon 2.048kB
- Step 1/3 : FROM busybox
- ---> 3a093384ac30
- Step 2/3 : ENV name www1707
- ---> Running in e43df73f1151
- Removing intermediate container e43df73f1151
- ---> 973f9b8b29b7
- Step 3/3 : ENTRYPOINT echo "Hello $name"
- ---> Running in 5efc3b5b3053
- Removing intermediate container 5efc3b5b3053
- ---> c9321b834dbb
- Successfully built c9321b834dbb
- Successfully tagged test017:latest
- root@docker-lab:~/017# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- test017 latest c9321b834dbb 6 seconds ago 1.2MB
- myimage latest c67728621bdd 33 hours ago 1.2MB
- busybox latest 3a093384ac30 7 days ago 1.2MB
- root@docker-lab:~/017# docker run test017
- Hello www1707
exec 格式:
<instruction> ["executable","param1","param2",...]
例如:
- RUN ["apt-get","install","python3"]
- CMD ["/bin/echo","Hello world"]
- ENTRYPOINT ["/bin/echo","Hello world"]
当指令执行时, 会直接调用 command, 不会被 shell 解析
- root@docker-lab:~/017# cat Dockerfile
- FROM busybox
- ENV name www1707
- ENTRYPOINT ["/bin/echo","Hello,$name"]
- root@docker-lab:~/017# docker build -t test-017 .
- Sending build context to Docker daemon 2.048kB
- Step 1/3 : FROM busybox
- ---> 3a093384ac30
- Step 2/3 : ENV name www1707
- ---> Running in 6a2a8dcbd2ab
- Removing intermediate container 6a2a8dcbd2ab
- ---> 026f3f3c154e
- Step 3/3 : ENTRYPOINT ["/bin/echo","Hello,$name"]
- ---> Running in 92c90db5bbc3
- Removing intermediate container 92c90db5bbc3
- ---> 1f01346313b5
- Successfully built 1f01346313b5
- Successfully tagged test-017:latest
- root@docker-lab:~/017# docker run test-017
- Hello,$name
- root@docker-lab:~/017# cat Dockerfile
- FROM busybox
- ENV name www1707
- ENTRYPOINT ["/bin/sh","-c","echo Hello,$name"]
- root@docker-lab:~/017# docker build -t test-017 .
- Sending build context to Docker daemon 2.048kB
- Step 1/3 : FROM busybox
- ---> 3a093384ac30
- Step 2/3 : ENV name www1707
- ---> Using cache
- ---> 026f3f3c154e
- Step 3/3 : ENTRYPOINT ["/bin/sh","-c","echo Hello,$name"]
- ---> Running in 459792a5b117
- Removing intermediate container 459792a5b117
- ---> d163360f72c5
- Successfully built d163360f72c5
- Successfully tagged test-017:latest
- root@docker-lab:~/017# docker run test-017
- Hello,www1707
CMD 和 ENTYRPOINT 推荐使用 exec 格式, 因为指令的可读性更强, 更容易理解.
RUN
RUN 使用两种格式都可以, 但是 RUN 一般用来安装应用和软件包, 推荐 shell 格式
RUN apt-get update && apt-get install -y VIM wget
先执行 update 保证后面安装的软件版本是最新的, 要不然会可能会安装一个早期的版本或者直接安装失败
CMD
CMD 支持三种格式
1,exec 格式 CMD ["executable","param1","param2"]
这是 CMD 推荐的格式
2,CMD ["param1","param2"]
这是为 ENTRYPOINT 提供额外参数时的格式, 此时 ENTRYPOINT 必须是 exec 格式
3,CMD command param1 param2
这是 shell 格式
第二种格式 CMD ["param1","param2"] 要与 exec 格式的 ENTRYPOINT 指令配合使用, 其用户是为 ENTRYPOINT 设置默认参数.
当 docker run 后面有参数时, CMD 指令将会被忽略
- root@docker-lab:~/017# cat Dockerfile
- FROM busybox
- CMD echo "Hello world"
- root@docker-lab:~/017# docker build -t test-017 .
- Sending build context to Docker daemon 2.048kB
- Step 1/2 : FROM busybox
- ---> 3a093384ac30
- Step 2/2 : CMD echo "Hello world"
- ---> Running in 15bd85e76424
- Removing intermediate container 15bd85e76424
- ---> 13e99c60b00d
- Successfully built 13e99c60b00d
- Successfully tagged test-017:latest
- root@docker-lab:~/017# docker run test-017
- Hello world
- root@docker-lab:~/017# docker run -it test-017
- Hello world
- root@docker-lab:~/017# docker run -it test-017 /bin/sh
- / #
- / # exit
- root@docker-lab:~/017#
- ENTRYPOINT
该指令可以让容器以应用程序或者服务运行. ENTYRPOINT 和 CMD 看上去很像, 他们都可以指定要执行的命令及参数. 但是 ENTYRPOINT 不会被忽略, 一定会被执行, 即使 docker run 后面指定了其他命令.
exec 格式 -- 推荐格式
- ENTYRPOINT ["executable","param1","param2"]
- root@docker-lab:~/017# cat Dockerfile
- FROM busybox
- ENTRYPOINT ["/bin/echo","Hello"]
- CMD ["world"]
- root@docker-lab:~/017# docker build -t test-017 .
- Sending build context to Docker daemon 2.048kB
- Step 1/3 : FROM busybox
- ---> 3a093384ac30
- Step 2/3 : ENTRYPOINT ["/bin/echo","Hello"]
- ---> Running in 5fca55e81dd9
- Removing intermediate container 5fca55e81dd9
- ---> 60978b547d5d
- Step 3/3 : CMD ["world"]
- ---> Running in b1f9da2b8ecf
- Removing intermediate container b1f9da2b8ecf
- ---> 1957f19e2cb7
- Successfully built 1957f19e2cb7
- Successfully tagged test-017:latest
- root@docker-lab:~/017# docker run test-017
- Hello world
- root@docker-lab:~/017# docker run -it test-017 www1707
- Hello www1707
shell 格式 -- 该格式会忽略掉 CMD 和 docker run 后面的参数
- ENTRYPOINT command param1 param2
- root@docker-lab:~/017# cat Dockerfile
- FROM busybox
- ENTRYPOINT echo hello
- CMD ["world"]
- root@docker-lab:~/017# docker build -t test-017 .
- Sending build context to Docker daemon 2.048kB
- Step 1/3 : FROM busybox
- ---> 3a093384ac30
- Step 2/3 : ENTRYPOINT echo hello
- ---> Running in 683c7c95a0bb
- Removing intermediate container 683c7c95a0bb
- ---> 4b76c9e22319
- Step 3/3 : CMD ["world"]
- ---> Running in 3464e96183d6
- Removing intermediate container 3464e96183d6
- ---> d636aed0e6b4
- Successfully built d636aed0e6b4
- Successfully tagged test-017:latest
- root@docker-lab:~/017# docker run test-017
- hello
- root@docker-lab:~/017# docker run -it test-017 www1707
- hello
最佳实践
1,RUN 指定用来安装应用和软件包
2,ENTRYPOINT 用来运行应用或者服务, 可以用 CMD 提供额外的参数, 还可以用 docker run 提供参数或者是替换掉 CMD 提供的参数
3,CMD 可以为容器设置默认的启动命令, 也可以用 docker run 替换掉
来源: http://www.bubuko.com/infodetail-2914756.html