Dockerfile: ADD vs COPY

转载:http://www.toutiao.com/i6313838452630618626/

本文将帮助你理解两个相似的Dockerfile 指令的区别——ADD 和 COPY。它们是什么样的,以及我们更推荐你使用哪一种(提示:当然不是ADD)

当从Dockerfile 中 build Docker 镜像时候,你可以选择两种指令来添加本地的目录或者文件到你的镜像中:ADD和COPY。这两种指令格式基本相同并且基本是同样的东西

ADD <src>... <dest>

COPY <src>... <dest>

在这两种情况中,目录或者文件(<src>)被复制并添加到容器的文件系统中的指定路径(<dest

>)

所以,如果这两种指令相等的话,那为什么还要同时存在呢以及你应该选择哪一种使用呢?继续读会有答案的。

当然如果你对他们之间的微小差别不感兴趣的话,只是想知道“我应该使用哪一个”,那么你只要知道:使用COPY即可。

最初

不像COPY指令,ADD从一开始就是Docker 的一部分,并且支持一些传统的技巧,而不仅仅是从build 上下文中复制文件。

ADD指令可以让你使用URL作为<src>参数。当遇到URL时候,可以通过URL下载文件并且复制到<dest>。

ADD http://foo.com/bar.go /tmp/main.go

以上文件会通过制定的URL下载下来,并且添加到容器的文件系统中的/tmp/main.go路径中。另外一种形式是让你简单地制定目的目录为下载文件:

ADD http://foo.com/bar.go /tmp/

因为<dest>以 / 结尾。Docker 会从URL推断文件名,并且添加到指定目录。在这个案例中,一个名叫/tmp/bar.go的文件会被添加到容器的文件系统。

ADD的另外一个特性是有能力自动解压文件。如果<src>参数是一个可识别的压缩格式(tar, gzip, bzip2, etc)的本地文件(所以实现不了同时下载并解压),就会被解压到指定容器文件系统的路径<dest>。

ADD /foo.tar.gz /tmp/

上述指令会使foo.tar.gz压缩文件解压到容器的/tmp目录。

有趣的是,URL下载和解压特性不能一起使用。任何压缩文件通过URL拷贝,都不会自动解压。

很明显,在简单的ADD 指令背后,有许多功能。这里有一段引用:

Currently the ADD command is IMO far too magical. It can add local and remote files. It will sometimes untar a file and it will sometimes not untar a file. If a file is a tarball that you want to copy, you accidentally untar it. If the file is a tarball in some unrecognized compressed format that you want to untar, you accidentally copy it. - amluto

意思是:目前ADD指令有点让人迷惑,有时候解压文件,有时候不解压文件,如果你想拷贝一个压缩文件,你会以为地解压。如果文件是某种不能识别的压缩文件,如果你想解压,你又会意外地复制它。

这种解释似乎是ADD尝试做的太多了,让用户有些疑惑。很明显,没人想要打破向后兼容性。所以决定新增一个行为更加明确的指令。

和ADD相似,但是功能少一些。

在Docker 1.0发布时候,包括了新指令COPY。不像是ADD,COPY 更加直接了当,只复制文件或者目录到容器里。

COPY不支持URL,也不会特别对待压缩文件。如果build 上下文件中没有指定解压的话,那么就不会自动解压,只会复制压缩文件到容器中。

COPY是ADD的一种简化版本,目的在于满足大多数人“复制文件到容器”的需求。

使用哪个?

假如目前还不明显的话,那Docker 团队的建议是在大多数情况下使用COPY。

真的,使用ADD的唯一原因就是你有一个压缩文件,你想自动解压到镜像中。

OK,但是如果想要从远程URLS 中获取包的话,ADD还是没用么?技术上来说,是的。但是在大多数情况下,你更有可能运行curl或者wget。看看下面的例子吧:

ADD http://foo.com/package.tar.bz2 /tmp/

RUN tar -xjf /tmp/package.tar.bz2 \

&& make -C /tmp/package \

&& rm /tmp/package.tar.bz2

这里我们有一个ADD指令,用于解析URL的压缩包,紧接着是RUN指令,用于解压这个压缩包。然后编译并尝试删除下载的压缩包。

很不幸,当这个压缩包压缩后,rm命令处于独立的镜像层。。

在这个案例中,你组好这样做:

RUN curl http://foo.com/package.tar.bz2 \

| tar -xjC /tmp/package \

&& make -C /tmp/package

这里,我们curl 这个压缩包并且通过管道传给tar 命令解压。这样就在同一层镜像那么我们就可以删除压缩包了。

始终还是会有理由使用ADD 一个远程文件到你的镜像中,但是这个一个明确的决定,而不是默认的选择。

最后,只要认准一个原则:使用COPY(除非你明确你需要ADD)

发布了112 篇原创文章 · 获赞 182 · 访问量 191万+
展开阅读全文

Dockers run hello-world 出错,什么原因??

03-28

镜像 ``` # docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/hello-world latest fce289e99eb9 2 months ago 1.84 kB ``` **使用run命令出现以下错误** ``` # docker run docker.io/hello-world container_linux.go:247: starting container process caused "process_linux.go:258: applying cgroup configuration for process caused \"Cannot set property TasksAccounting, or unknown property.\"" /usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:258: applying cgroup configuration for process caused \"Cannot set property TasksAccounting, or unknown property.\"". ``` 我的docker.service: ``` # cat /usr/lib/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=http://docs.docker.com # After=network-online.target firewalld.service # Wants=networkonline.target After=network.target Wants=docker-storage-setup.service Requires=docker-cleanup.timer [Service] Type=notify NotifyAccess=main EnvironmentFile=-/run/containers/registries.conf EnvironmentFile=-/etc/sysconfig/docker EnvironmentFile=-/etc/sysconfig/docker-storage EnvironmentFile=-/etc/sysconfig/docker-network Environment=GOTRACEBACK=crash Environment=DOCKER_HTTP_HOST_COMPAT=1 Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin ExecStart=/usr/bin/dockerd-current \ --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \ --default-runtime=docker-runc \ --exec-opt native.cgroupdriver=systemd \ --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \ --init-path=/usr/libexec/docker/docker-init-current \ --seccomp-profile=/etc/docker/seccomp.json \ $OPTIONS \ $DOCKER_STORAGE_OPTIONS \ $DOCKER_NETWORK_OPTIONS \ $ADD_REGISTRY \ $BLOCK_REGISTRY \ $INSECURE_REGISTRY \ $REGISTRIES ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=1048576 LimitNPROC=1048576 LimitCORE=infinity TimeoutStartSec=0 Restart=on-abnormal KillMode=process [Install] WantedBy=multi-user.target ``` 到底是哪里有问题??求大佬们支支教 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览