Docker笔记三:Dockerfile定制镜像
镜像的定制实际上就是定制每一层所添加的配置、文件。
使用Dockerfile可以记录每一层操作的命令,然后用它来定制镜像。
Dockerfile中每一条命令对应一层的构建。
在 Dockerfile 文件所在目录执行:
docker build -t <镜像> .
docker build 命令构建镜像,其实并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。
Dockerfile指令
FROM 指定基础镜像
FROM 是必备的指令,并且必须是第一条指令。
如果不以任何镜像为基础,可以使用FROM scratch
RUN 执行命令
执行命令行命令
shell 格式: RUN <命令>
exec 格式:RUN ["可执行文件", "参数1", "参数2"],这更像是函数调用中的格式。
每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。
COPY 复制文件
从构建上下文中的源路径copy到镜像中的目标路径
格式:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。<目标路径> 可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR 指令来指定)
ADD 更高级的复制文件
ADD和Copy的功能和用法类似,但是在COPY的基础上又加了一些功能。
- <源路径> 可以是一个 URL
-<源路径> 为一个 tar 压缩文件
压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令将会自动解压缩
CMD 容器启动命令
指定容器默认的启动命令。可以使用docker run修改容器启动命令
shell 格式:CMD <命令>
exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
参数列表格式:CMD ["参数1", "参数2"...]
ENTRYPOINT 入口点
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。ENTRYPOINT 在运行时也可以替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 --entrypoint 来指定。
当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:<ENTRYPOINT> "<CMD>"
使用场景:
1.让镜像可以接受命令参数
- 容器运行前的准备工作 可以把ENTRYPOINT写成脚本,然后CMD作为脚本参数
ENV 设置环境变量
格式有两种:
1.ENV <key> <value>
2.ENV <key1>=<value1> <key2>=<value2>...
ARG 构建参数
格式:ARG <参数名>[=<默认值>]
ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。
Dockerfile 中的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 docker build 中用 --build-arg <参数名>=<值> 来覆盖。
VOLUME 定义匿名卷
格式为:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
VOLUME /data
这里的 /data 目录就会在运行时自动挂载为匿名卷,任何向 /data 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。比如:
docker run -d -v mydata:/data xxxx
EXPOSE 声明端口
格式为 EXPOSE <端口1> [<端口2>...]。
仅仅是声明而已,不会在宿主机进行端口映射。
可以在运行时使用随机端口映射,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
WORKDIR 指定工作目录
格式为 WORKDIR <工作目录路径>
USER 指定当前用户
格式:USER <用户名>[:<用户组>]
USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层。
HEALTHCHECK 健康检查
格式:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
ONBUILD 为他人做嫁衣裳
格式:ONBUILD <其它指令>
在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
参考:https://yeasy.gitbooks.io/docker_practice/content/image/dockerfile/