Dockerfile指令
Docker指令
COPY 复制文件:
就是一个单纯的复制命令
格式:
COPY <源路径>…<目标路径>
COPY [“<源路径>”…”<目标路径>”]
和RUN指令一样,COPY指令也有两种格式,一种是类似于命令行,一种是类似于函数调用。
COPY指令是指从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目的路径> 位置。比如:
COPY package.json /usr/src/app/
就是把package.json这个json文件复制到容器里的/usr/src/app/文件夹内
<源路径>可以是多个,甚至可以是通配符,其通配符规则要满足Go的filepath.Math规则,如:
COPY home* /mydir/
COPY home?.txt /mydir/
<目的路径>可以是容器中的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用WORKDIR指令来指定)。目标路径不需要提前创建,如果目录不存在会在复制文件之前先行创建。
使用COPY命令进行复制的时候,源文件的特性都会保留,如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用。特别是构建相关文件都在使用Git进行管理的时候。
ADD更高级的复制文件
ADD 指令和 COPY的格式和性质基本一样。但是在COPY基础上增加了一些功能。
比如 <源路径> 可以是一个URL,这种情况下,Docker引擎会试图去下载这个链接的文件放到 <目标路径> 去。下载后的文件权限自动设置为600,如果并不是想要的权限,那么还需要额外一层的RUN命令进行权限调整。所以不如直接使用RUN命令,然后用wget或者curl工具下载,处理权限、解压缩、然后清理无用的文件更合理。因此,这个功能其实并不适用,而且不推荐使用。
如果 <源路径> 为一个tar压缩文件的话,压缩格式为gzip,bzip以及xz的情况下,ADD指令会自动解压这个文件到 <目的路径> 去。
例如:
FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
...
ADD指令会令镜像构建缓存失效,从而可能令镜像构建变得缓慢。
实际上如果需要解压的话就用ADD,否则就用COPY。
CMD容器启动命令
实际上在需要输入命令和参数的时候就要调用CMD命令
CMD指令和RUN指令相似,也是两种格式。
shell格式:CMD <命令>
exec格式:CMD[“可执行文件”, “参数1”, “参数2”…]
参数列表格式:CMD[“参数1”, “参数2”…]。在指定了ENTRYPOINT指令后用CMD指定具体的参数。
容器实际上就是一个进程,当容器启动的时候,也就是一个进程的创建,需要命令和参数,这个任务就有CMD命令来做。
在执行的时候可以用新的命令来代替,镜像设置中的这个默认命令,比如Ubuntu中默认CMD是 /bin/bash/,如果直接docker run –it Ubuntu:16.04,那么会直接进入bash,如 docker run –it Ubuntu:16.04 cat /etc/os-release就会替代默认的命令,输出版本信息。
在指令格式上推荐使用exec格式,这类格式解析式会被解析成json数组,因此要使用双引号,不要用单引号。
如果使用shell格式的话,实际的命令会被包装成sh –c的参数的形式进行执行。比如:
CMD echo $HOME
在实际执行中变成
CMD [“sh”, “-c”, “echo $HOME”]
ENTRYPOINT 入口点
命令的格式和CMD一样
和CMD命令类似,都是当需要输入命令和参数的时候调用的命令,但是他的功能比CMD繁琐一些,例如:
一种情况,把镜像当做命令
现在我们来创建一个获取公网IP的镜像。
FROM ubuntu:16.4
RUN apt-get update \
&& apt-get install –y curl \
&& rm -rf /var/lib/apt/lists/*
# 运行了三条命令,第一条是更新源,第二条是安装curl,curl就是获取网页信息的
# 一个工具,例如 curl https://www.baidu.com,就会获取到百度的主页的html,
# 第三条命令就是删除安装软件带来的垃圾。
CMD [“curl”, “-s”, “http://ip.cn”]
先创建好镜像
docker build –t myip .
然后运行这个容器
docker run myip
命令是有参数的,但是当我们需要加参数的时候
看到报错了,因为上面讲CMD的时候说过,如果命令后面加参数,这个参数会替代默认的CMD,正式要解决这个问题就有了ENTRYPOINT。
Dockerfile改为:
FROM ubuntu:16.4
RUN apt-get update \
&& apt-get install –y curl \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT[“curl”, “-s”, “http://ip.cn”]
完成上面的步骤,然后运行容器
EVN设置环境变量
格式:
ENV <key> <value>
ENV <key1>=<valule1> <key2>=<valule2>
就是设置环境变量。无论是后边的指令,还是运行时的指令都可以用这里定义的环境变量。
ARG构建参数
格式:
ARG <参数名> [=<默认值>]
效果和EVN一样都是设置环境变量,但是容器结束后,ARG设置的环境变量就没了,但是在docker history中还能看到,就是不能用了而已。
EXPOSE 声明端口
格式:
EXPOSE<端口1> [<端口2>…]
WORKDIR 指定工作目录
格式:
WORKDIR <工作目录路径>