容器启动命令
CMD
CMD
用来设置容器启动时默认会执行的命令。
它会在容器启动
docker run
时默认执行。如果
docker run
启动容器时指定了其它命令,则CMD
命令会被忽略。如果定义了多个
CMD
,只有最后一个会被执行。
它的格式是:CMD ["要执行的命令"]
或者 CMD []
。例如,先构建下面的Dockerfile
。
FROM ubuntu:20.04
ENV VERSION=2.0.1
RUN apt-get update && \
apt-get install -y wget && \
wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz
然后再执行如下命令。
> docker image history ipinfo
可以看到它已经执行了一个默认的CMD
命令。
IMAGE CREATED CREATED BY SIZE COMMENT
db75bff5e3ad 24 hours ago RUN /bin/sh -c apt-get update && apt-get… 50MB buildkit.dockerfile.v0
<missing> 24 hours ago ENV VERSION=2.0.1 0B buildkit.dockerfile.v0
<missing> 7 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
在Dockerfile
中加入CMD []
。
FROM ubuntu:20.04
ENV VERSION=2.0.1
RUN apt-get update && \
apt-get install -y wget && \
wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz
CMD []
构建后再执行时会报错。
> docker build -t test .
> docker run -it test
docker: Error response from daemon: No command specified.
See 'docker run --help'.
ENTRYPOINT
ENTRYPOINT
也可以设置容器启动时要执行的命令,但它和CMD
是有区别的。
CMD
可以在docker run
时传入其它命令,覆盖掉之前的CMD
。ENTRYPOINT
所设置的命令是一定会被执行的。
ENTRYPOINT
和CMD
可以联合使用:由ENTRYPOINT
设置执行的命令,而用CMD
传递参数。
有如下的Dockerfile
。
FROM ubuntu:20.04
CMD ["echo", "hello docker"]
执行下面的构建命令。
> docker build -t demo .
执行后可以看到CMD
会被新传递的命令覆盖。
> docker run -it demo
hello docker
> docker run -it demo echo "hello world"
hello world
有如下的Dockerfile
。
FROM ubuntu:20.04
ENTRYPOINT ["echo", "hello docker"]
执行下面的构建命令。
> docker build -t demo .
执行后可以看到ENTRYPOINT
不会被新传递的命令覆盖。
> docker run -it demo
hello docker
> docker run -it demo echo "hello world"
hello docker echo hello world
有如下Dockerfile
。
FROM ubuntu:20.04
ENTRYPOINT ["echo"]
CMD []
执行下面的构建命令。
> docker build -t demo .
运行Docker容器。
> docker run -it demo
执行后可以看到什么都没有显示,这是因为CMD
将""
传给了ENTRYPOINT
要执行的命令echo
,所以什么都没显示。
运行下面的Docker容器。
> docker run -it demo test
test
则可以看到ENTRYPOINT
和CMD
放在一起时的效果。
命令的shell格式和exec格式
shell
格式。
CMD echo "hello docker"
。ENTRYPOINT echo "hello docker"
。
exec
格式。
ENTRYPOINT ["echo", "hello docker"]
。CMD ["echo", "hello docker"]
。
建议使用exec
格式,因为脚本可以这样传参数。
FROM ubuntu:20.04
ENV NAME=docker
CMD echo "hello $NAME"
但exec
不能这样写。
FROM ubuntu:20.04
ENV NAME=docker
CMD ["echo", "hello $NAME"]
像上面那样写的输出会是下面这样的。
hello $NAME
而不是像下面所希望的那样。
hello docker
所以exec
只能这样写。
FROM ubuntu:20.04
ENV NAME=docker
CMD ["sh", "-c", "echo hello $NAME"]
感谢支持
更多内容,请移步《超级个体》。