我见过许多具有各种语法的 Dockerfile。他们中的一些人CMD不使用括号,其中一些人使用括号。根据我的实验,这两个是等价的:
CMD ["/bin/ping", "localhost"]
CMD /bin/ping localhost
Run Code Online (Sandbox Code Playgroud)
但事实并非如此,ENTRYPOINT根据我的实验,这些并不相同,只有带括号的版本才有效。
ENTRYPOINT ["/docker-entrypoint.sh"]
ENTRYPOINT /docker-entrypoint.sh
Run Code Online (Sandbox Code Playgroud)
我正在试验这些文件:
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"
Run Code Online (Sandbox Code Playgroud)
docker-entrypoint.sh
#!/bin/bash
echo "PASSED ARGUMENTS"
echo "$@"
exec "$@"
Run Code Online (Sandbox Code Playgroud)
配置:
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
Run Code Online (Sandbox Code Playgroud)
我认为支架版本是首选方式,但我想知道为什么甚至允许构建非支架版本?它有什么好处吗?CMD当ENTRYPOINT仅适用于支架版本时,为什么同时适用于两个版本?
Dav*_*aze 10
有两个规则:
/bin/sh -c '...'.ENTRYPOINT和CMD被组合成单个命令。还有一个细节:如果你打电话/bin/sh -c 'command',其余参数成为位置参数$0,$1,等扩大的command字符串; 它们不会作为参数进一步传递给command.
所以如果你的 Dockerfile 说
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/command.sh"]
Run Code Online (Sandbox Code Playgroud)
然后当 Docker 启动容器时,它们将组合成一个命令行
/entrypoint.sh /command.sh
Run Code Online (Sandbox Code Playgroud)
但如果你用字符串形式来做
ENTRYPOINT /entrypoint.sh
CMD /command.sh
Run Code Online (Sandbox Code Playgroud)
你会得到
/bin/sh -c '/entrypoint.sh' /bin/sh -c '/command.sh'
Run Code Online (Sandbox Code Playgroud)
它计算字符串/entrypoint.sh并按原样执行它,没有参数;命令丢失。
通常,您希望命令部分成为标准的 shell 命令(docker run --rm -it some-image /bin/sh对于调试非常有用)。为了支持这一点,ENTRYPOINT必须是 JSON 数组形式,并且它需要确保运行在其参数中传递的命令(在 shell 脚本中,以 结尾exec "$@")。
| 归档时间: |
|
| 查看次数: |
1276 次 |
| 最近记录: |