我看过许多使用各种语法的Dockerfile。其中一些使用不带方括号的CMD
,其中一些使用方括号。根据我的实验,这两个是等效的:
CMD ["/bin/ping", "localhost"]
CMD /bin/ping localhost
但这对于
ENTRYPOINT
是不正确的。根据我的实验,它们并不相同,只有带括号的版本有效。ENTRYPOINT ["/docker-entrypoint.sh"]
ENTRYPOINT /docker-entrypoint.sh
我正在实验这些文件:
Dockerfile:
FROM debian:wheezy
COPY docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
# WORKS AS EXPECTED - FIRST PASS EXECUTION TO /docker-entrypoint.sh THEN TO CMD
ENTRYPOINT ["/docker-entrypoint.sh"]
# PRINTS "PASSED ARGUMENTS" AND EXITS (CMD IS NOT EXECUTED)
# ENTRYPOINT /docker-entrypoint.sh
# WORKS
CMD ["/bin/ping", "localhost"]
# WORKS
# CMD /bin/ping localhost
# ERROR
# CMD "/bin/ping localhost"
docker-entrypoint.sh
#!/bin/bash
echo "PASSED ARGUMENTS"
echo "$@"
exec "$@"
组态:
wakatana@ubuntu:~/df$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.3 LTS
Release: 18.04
Codename: bionic
wakatana@ubuntu:~/df$ docker info
Client:
Debug Mode: false
Server:
Containers: 44
Running: 8
Paused: 0
Stopped: 36
Images: 98
Server Version: 19.03.5
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: systemd
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
init version: fec3683
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 4.15.0-99-generic
Operating System: Ubuntu 18.04.3 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.83GiB
Name: ubuntu
ID: GIQ3:BYEM:O3GZ:OWNP:VROK:V3IV:SVMI:MRZ7:CLHG:GDBR:PG3S:6NQU
Docker Root Dir: /var/lib/docker
Debug Mode: false
Username: xclbr
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
WARNING: No swap limit support
wakatana@ubuntu:~/df$ docker --version
Docker version 19.03.5, build 633a0ea838
我认为最好使用括号版本,但是我想知道为什么甚至允许构建非括号版本?有好处吗?当
CMD
仅适用于括号版本时,为什么ENTRYPOINT
适用于两个版本? 最佳答案
有两个规则:
/bin/sh -c '...'
中。 ENTRYPOINT
和CMD
为combined into a single command。 还有一个细节:如果您调用
/bin/sh -c 'command'
,剩下的所有参数将成为位置参数$0
,$1
等,以扩展command
字符串;它们不会进一步作为参数传递给command
。因此,如果您的Dockerfile说
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/command.sh"]
然后当Docker启动容器时,它们将合并为一个命令行
/entrypoint.sh /command.sh
但是如果您使用字符串形式
ENTRYPOINT /entrypoint.sh
CMD /command.sh
你会得到
/bin/sh -c '/entrypoint.sh' /bin/sh -c '/command.sh'
它计算字符串
/entrypoint.sh
并按原样执行它,不带参数;命令丢失。通常,您希望允许命令部分成为标准的shell命令(
docker run --rm -it some-image /bin/sh
对于调试非常有用)。为此,ENTRYPOINT
必须为JSON数组形式,并且需要确保运行在其参数中传递的命令(在shell脚本中,以exec "$@"
结尾)。关于docker - CMD和ENTRYPOINT支架与非支架版本,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62206384/