目录
- Dockfile指令详解
- 1. COPY 复制文件
- 2. ADD 更高级的复制文件
- 3. CMD 容器启动命令
Dockfile指令详解
Dockerfile 功能强大,提供了10多个指令。
1. COPY 复制文件
格式:
- COPY <源路径> … <目标路径>
- COPY ["<源路径>" … “<目标路径>”]
与RUN 指令一样,其有2种格式,一种类似于命令行,一种类似于函数调用。
COPY 指令将从构建context目录中 <源路径> 的文件/目录 复制到新的一层的镜像内的 <目标路径> 位置。
如:
COPY README.md /usr/src/app/
源路径可以是多个,支持通配符,如:
COPY user_* /mydir/
COPY product-?.log /mydir/
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- <目标路径> ,可以是container内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用WORKDIR来指定);
- 使用 COPY指令,源文件的各种元数据属性都会保留。如读、写、执行权限、文件变更时间等;
2. ADD 更高级的复制文件
ADD 指令与 COPY 指令的格式及性质基本一致,但是在COPY的基础上增加了一些功能。
<源路径> 如果是一个tar压缩文件(gzip、bzip2、xz等)的话,ADD指令将会自动解压缩这个压缩文件到 <目标路径> 中去。
某种情况下,这个自动解压缩的功能很有用,如官方镜像 ubuntu 中:
FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
…
Docker官方的最佳实践中要求,尽可能的使用COPY,因为其语义很明确,就是复制文件而已,而ADD则包含了更复杂的功能,其行为也不一定很清晰。
最适合使用ADD的场景,就是需要自动解压缩的场合
在COPY和ADD对场景的选择,可以遵循这样的原则,所有文件的复制均使用COPY,仅在需要自动解压缩的场合下使用ADD.
Dockerfile 功能强大,提供了10多个指令。
3. CMD 容器启动命令
与RUN 指令相似,其有2种格式,一种类似于命令行,一种类似于函数调用。
格式:
- shell 格式: CMD <命令>
- exec 格式: CMD [“可执行文件”, “参数1”, “参数2” …]
- 参数列表饿死: CMD [“参数1”, “参数2”, …]。在指定了 ENTRYPOINT 指令后,用CMD指定具体的参数。
Docker不是虚拟机,容器就是进程,既然是进程,那么在启动容器的时候,就需要指定所运行的程序及参数。CMD 指令就是用于指定默认的容器主进程的启动命令的。
在运行时可以指定新的命令来替代mirror设置中的这个默认命令,如 ubuntu 镜像默认的 CMD 是 /bin/bash,如果直接 docker run -it ubuntu的话,就会直接进入bash。
我们可以在运行时指定运行级别的命令,如:
docker run -it ubuntu cat /etc/os-release
这就是用 cat /etc/os-release 命令替换了默认的 /bin/bash 了。
在指令格式上,一般推荐使用 exec 格式,这类格式在会被解析为JSON数组,因此一定要使用双引号",而不是单引号’。
如果使用shell 格式的话, 实际的命令会被包装成为 sh -c 的参数的形式执行,如:
CMD echo ‘Hello, Docker’
在实际执行中,会将其变更为:
CMD [“sh”, “-c”, “echo ‘Hello,Docker’”]
Docker 不是虚拟机,容器中的应用都应该以前台方式运行,而不是像虚拟机、物理机里面那样,用upstart | systemd 等方式去启动后台服务,容器内没有后台的概念。
如错误启动容器内nginx的方式:
CMD service nginx start
实际上会被理解位 CMD [“sh”, “-c”, “service nginx start”],实际上主进程是 sh,那么当 service nginx start 命令结束后,sh也就结束了,sh作为主进程退出了,自然会令容器退出。
正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行,如:
CMD [“nginx”, “-g”, “daemon off;”]