1. Dockerfile里指定执行命令用RUN、ENTRYPOING和CMD有何不同?
- RUN仅仅是在 docker build 时运行的。
- docker build完成之后会打包成一个镜像,只有执行docker run后,才会执行CMD或者ENTRYPOINT。
- ENTRYPOINT和CMD的不同点在于执行docker run时参数传递方式。
区别如下:
1.1 CMD指定的命令可以被docker run传递的命令覆盖。
1.1.1 Dockerfile仅仅使用CMD指令
Dockerfile:
FROM ubuntu
CMD ["echo", "far"]
复制代码
➜ docker build -t run-test:0.1 .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM ubuntu
---> 93fd78260bd1
Step 2/2 : CMD ["echo", "far"]
---> Running in 0f97a65b839e
Removing intermediate container 0f97a65b839e
---> 22e6e82769ea
Successfully built 22e6e82769ea
Successfully tagged run-test:0.1
>>> 我们可以看到,构建过程中并没有执行CMD中的echo指令,只是看到了构建信息 <<<
复制代码
➜ docker run run-test:0.1
far
>>> 我们可以看到,在执行docker run后,CMD中的echo命令被执行了 <<<
复制代码
➜ docker run run-test:0.1 echo bor
bor
>>> 我们可以看到,在执行docker run后,CMD中的echo命令被docke run的命令参数覆盖了。 <<<
复制代码
1.1.2 Dockerfile即使用CMD又使用RUN
Dockerfile:
FROM ubuntu
CMD ["echo", "far"]
RUN ["echo", "foo"]
复制代码
➜ docker build -t run-test:0.1 .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM ubuntu
---> 93fd78260bd1
Step 2/3 : CMD ["echo", "far"]
---> Running in 44ef2a9c88ca
Removing intermediate container 44ef2a9c88ca
---> 559ca9f008a5
Step 3/3 : RUN ["echo", "foo"]
---> Running in f801910112ab
foo
Removing intermediate container f801910112ab
---> 6d042893d5e9
Successfully built 6d042893d5e9
Successfully tagged run-test:0.1
>>> 我们可以看到,构建过程中并没有执行CMD的echo指令,但是执行了RUN指令 <<<
复制代码
➜ docker run run-test:0.1
far
>>> 我们可以看到,在执行docker run后,CMD中的echo命令被执行了 <<<
复制代码
➜ docker run run-test:0.1 echo bor
bor
>>> 我们可以看到,在执行docker run后,CMD中的echo命令被docke run的命令参数覆盖了。 <<<
复制代码
1.2 ENTRYPOINT会把容器名后面的所有内容都当成参数传递给其指定的命令
1.1.1 Dockerfile仅仅使用ENTRYPOINT指令
Dockerfile:
FROM ubuntu
ENTRYPOINT ["echo", "far"]
复制代码
➜ docker build -t run-test:0.1 .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM ubuntu
---> 93fd78260bd1
Step 2/2 : ENTRYPOINT ["echo", "far"]
---> Running in ede61562f973
Removing intermediate container ede61562f973
---> 76dd760e3382
Successfully built 76dd760e3382
Successfully tagged run-test:0.1
>>> 我们可以看到,构建过程中并没有执行echo指令,只是看到了构建信息 <<<
复制代码
➜ docker run run-test:0.1
far
>>> 我们可以看到,在执行docker run后,ENTRYPOINT中的echo命令被执行了 <<<
复制代码
➜ docker run run-test:0.1 echo bor
far echo bor
>>> 我们可以看到,在执行docker run后,ENTRYPOINT会把容器名后面的所有内容都当成参数传递给其指定的命令 <<<
>>> 2. 另外,我们可以发现,在Dockerfile中,ENTRYPOINT指定的参数比运行docker run时指定的参数更靠前。
例如此处实际上是执行了:echo "far echo bor"
复制代码
1.1.2 Dockerfile即使用ENTRYPOINT又使用RUN
Dockerfile:
FROM ubuntu
ENTRYPOINT ["echo", "far"]
RUN ["echo", "foo"]
复制代码
➜ docker build -t run-test:0.1 .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM ubuntu
---> 93fd78260bd1
Step 2/3 : ENTRYPOINT ["echo", "far"]
---> Running in b0e86020ab3e
Removing intermediate container b0e86020ab3e
---> 5d389a86c0dc
Step 3/3 : RUN ["echo", "foo"]
---> Running in f4eb7745c7a3
foo
Removing intermediate container f4eb7745c7a3
---> 323ab1e07c2e
Successfully built 323ab1e07c2e
Successfully tagged run-test:0.1
>>> 我们可以看到,构建过程中并没有执行ENTRYPOINT的echo指令,但是执行了RUN指令 <<<
复制代码
➜ docker run run-test:0.1
far
>>> 我们可以看到,在执行docker run后,ENTRYPOINT中的echo命令被执行了 <<<
复制代码
➜ docker run run-test:0.1 echo bor
far echo bor
>>> 1. 我们可以看到,在执行docker run后,ENTRYPOINT会把容器名后面的所有内容都当成参数传递给其指定的命令。 <<<
>>> 2. 另外,我们可以发现,在Dockerfile中,ENTRYPOINT指定的参数比运行docker run时指定的参数更靠前。
例如此处实际上是执行了:echo "far echo bor"
复制代码