Dockerfile指令
Posted smart-girl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dockerfile指令相关的知识,希望对你有一定的参考价值。
本文来自技术分享
1. COPY 复制文件
格式:
shell 格式:COPY <源路径>... <目标路径>
exec 格式:COPY ["<源路径1>",... "<目标路径>"]
说明:
两种格式,一种类似于命令行,一种类似于函数调用。
COPY 指令将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。
示例:
COPY package.json /usr/src/app/
<源路径>可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 filepath.Match 规则,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
2. ADD 更高级的复制文件
格式:
ADD <源路径>... <目标路径>
ADD ["<源路径1>",... "<目标路径>"]
说明:
ADD 指令和 COPY 的格式和性质基本一致。但是在COPY 基础上增加了一些功能。
<源路径> 可以是一个 URL ,这种情况下,Docker引擎会试图去下载这个链接的文件放到 <目标路径> 去。下载后的文件权限自动设置为 600 ,如果这并不是想要的权限,那么还需要增加额外的一层 RUN 进行权限调整,另外,如果下载的是个压缩包,需要解压缩,也一样还需要额外的一层 RUN 指令进行解压缩。不推荐使用。
如果<源路径>为一个 tar 压缩文件的话,压缩格式为 gzip , bzip2 以及 xz 的情况下, ADD 指令将会自动解压缩这个压缩文件到 <目标路径> 去。
示例:
ADD mqtt-service.sh $MQTT_SERVICE/
3. CMD 容器启动命令
格式:
CMD 指令的格式和 RUN 相似,也是两种格式:
l shell 格式: CMD <命令>
l exec 格式: CMD ["可执行文件", "参数1", "参数2"...]
l 参数列表格式: CMD ["参数1", "参数2"...] 。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数
说明:
Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。 CMD 指令就是用于指定默认的容器主进程的启动命令的。
在运行时可以指定新的命令来替代镜像设置中的这个默认命令,比如, 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 $HOME
在实际执行中,会将其变更为:
CMD [ "sh", "-c", "echo $HOME" ]
4. ENTRYPOINT入口点
格式:
l shell 格式: ENTRYPOINT <命令>
l exec 格式: ENTRYPOINT ["可执行文件", "参数1", "参数2"...]
说明:
ENTRYPOINT 的格式和 RUN 指令格式一样,分为 exec 格式和 shell 格式。
ENTRYPOINT的目的和CMD 一样,都是在指定容器启动程序及参数。ENTRYPOINT 在运行时也可以替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 --entrypoint 来指定。
当指定了 ENTRYPOINT 后, CMD 的含义就发生了改变,不再是直接的运行其命令,而是将CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:
示例:
ENTRYPOINT ["./mqtt-service.sh"]
5. ENV设置环境变量
格式:
ENV
ENV
说明:
这个指令很简单,就是设置环境变量而已,无论是后面的其它指令,如 RUN ,还是运行时的应用,都可以直接使用这里定义的环境变量。
下列指令可以支持环境变量展开:
ADD 、 COPY 、 ENV 、 EXPOSE 、 LABEL 、 USER 、 WORKDIR 、 VOLUME 、 STOPSIGNAL 、 ONBUILD 。
6. ARG构建参数
格式:
ARG <参数名>[=<默认值>]
说明:
构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是, ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。
Dockerfile 中的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令docker build 中用 --build-arg <参数名>=<值> 来覆盖。
7. VOLUME定义匿名卷
格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
说明:
容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
VOLUME /data
这里的 /data 目录就会在运行时自动挂载为匿名卷,任何向 /data 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。比如:
docker run -d -v mydata:/data xxxx
在这行命令中,就使用了 mydata 这个命名卷挂载到了 /data 这个位置,替代了Dockerfile 中定义的匿名卷的挂载配置。
8. EXPOSE声明端口
格式:
EXPOSE <端口1> [<端口2>...]
说明:
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
示例:
EXPOSE 8080/tcp
9. WORKDIR指定工作目录
格式:
WORKDIR <工作目录路径>
说明:
使用 WORKDIR 指令可以来指定工作目录( 或者称为当前目录) ,以后各层的当前目录就被改为指定的目录,如该目录不存在, WORKDIR 会帮你建立目录。
示例:
WORKDIR ${MQTT_SERVICE}
10. USER指定当前用户
格式:
USER <用户名>
说明:
USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层。 WORKDIR 是改变工作目录, USER 则是改变之后层的执行 RUN , CMD 以及 ENTRYPOINT 这类命令的身份。
如果以 root 执行的脚本,在执行期间希望改变身份,比如希望以某个已经建立好的用户来运行某个服务进程,不要使用 su 或者 sudo ,这些都需要比较麻烦的配置,而且在 TTY 缺失的环境下经常出错。建议使用 gosu 。
# 建立 redis 用户,并使用 gosu 换另一个用户执行命令
RUN groupadd -r redis && useradd -r -g redis redis
# 下载 gosu
RUN wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64"
&& chmod +x /usr/local/bin/gosu
&& gosu nobody true
# 设置 CMD,并以另外的用户执行
CMD [ "exec", "gosu", "redis", "redis-server" ]
11. HEALTHCHECK健康检查
格式:
HEALTHCHECK [选项] CMD <命令> :设置检查容器健康状况的命令
HEALTHCHECK NONE :如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
说明:
HEALTHCHECK 指令是告诉 Docker 应该如何进行判断容器的状态是否正常,这是 Docker 1.12引入的新指令。
HEALTHCHECK 支持下列选项:
--interval=<间隔> :两次健康检查的间隔,默认为 30 秒;
--timeout=<时长> :健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被 视为失败,默认 30 秒;
--retries=<次数> :当连续失败指定次数后,则将容器状态视为 unhealthy ,默认 3次。
示例:
FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://localhost/ || exit 1
健康检查命令的输出( 包括 stdout 以及 stderr ) 都会被存储于健康状态里,可以用 docker inspect 来查看
$ docker inspect --format '{{json .State.Health}}' web | python -m json.tool
12. ONBUILD为他人做嫁衣
格式:
ONBUILD <其它指令>
说明:
ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN , COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
示例:
FROM node:slim
RUN mkdir /app
WORKDIR /app
ONBUILD COPY ./package.json /app
ONBUILD RUN [ "npm", "install" ]
ONBUILD COPY . /app/
CMD [ "npm", "start" ]
构建镜像my-node
FROM my-node
这个镜像构建时会执行以上ONBUILD中的三个命令。
以上是关于Dockerfile指令的主要内容,如果未能解决你的问题,请参考以下文章