Dcokerfile 包含了所有用来组装image的命令。通过docker build来自动创建image。
用法
需要指定本地路径作为上下文目录,路径是本地系统的目录。而docker build会递归的从指定目录去寻找。
$ docker build .
Sending build context to Docker daemon 6.51 MB ...
一般情况下,指定空目录且Dockerfile也在该目录中。当然也可以使用-f 来指定Dockerfile的位置。
$ docker build -f /path/to/a/Dockerfile .
如果构建成功,您可以指定要保存的image的存储库和标记:
zane@zane-V:~/mydockerbuild$ docker build -t aiapple .
#生成了aiapple存储库的image。
zane@zane-V:~/mydockerbuild$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE aiapple latest d2f5f84bec87 26 seconds ago 275.1 MB
在创建image后,指定新image标记到多个存储库;
zane@zane-V:~/mydockerbuild$ docker build -t zane/aiapple:007 -t zane/aiapple:009 . Sending build context to Docker daemon 2.048 kB Step 1 : FROM docker/whalesay:latest ---> 6b362a9f73eb Step 2 : RUN apt-get -y update && apt-get install -y fortunes ---> Using cache ---> 845104a653c5 Step 3 : CMD /usr/games/fortune -a | cowsay ---> Using cache ---> d2f5f84bec87 Successfully built d2f5f84bec87 zane@zane-V:~/mydockerbuild$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ziapple latest d2f5f84bec87 7 minutes ago 275.1 MB aiapple latest d2f5f84bec87 7 minutes ago 275.1 MB zane/aiapple 007 d2f5f84bec87 7 minutes ago 275.1 MB zane/aiapple 009 d2f5f84bec87 7 minutes ago 275.1 MB
注意:
为了创建image的效率,docker build 使用中间image(cache)。
格式
Dockerfile第一行必须是:
‘FROM’用来指定基础image。
语法解析器
两种无效的写法:
解析器要连续书写
# direc
\tive=value
解析器出现了两次
# directive=value1
# directive=value2
FROM ImageName
解析器被认为是注释,因为在创建image说的之后。
FROM ImageName
# directive=value
无效解析器被认为是注释,而注释之后的解析器 认为无效
# unknowndirective=value
# knowndirective=value
所有解析器指令必须位于Dockerfile的最顶端。类似脚本中#!/bin/bash ;
惯例解析器,小写,以及后面紧跟空行。
环境替换
环境变量值,可以使用在Dockerfile中。
在Dockerfile中使用$variable_name,
bash的几个特性:
FROM busybox ENV foo /bar WORKDIR ${foo} # WORKDIR /bar ADD . $foo # ADD . /bar COPY \$foo /quux # COPY $foo /quux
ENV abc=hello ENV abc=bye def=$abc ENV ghi=$abc
def的值是hello 不是bye。而ghi的值是bye。
可见是一行行整体执行的。
.dockerignore file
在docker发送上下文给 docker daemon 之前,会寻找.dockerignore file文件,去排除一些不需要的文件,或者很大的文件
不把这些文件发送给docker daemon,提升效率。而如果之后需要用到,则可以使用 ADD 或者 COPY 把他们放进image中。
.dockerignore 文件第一行是:
# comment
.dockerignore 支持正则表达式,
# comment */temp* */*/temp* temp?
具体排除规则: filepath.Match rules
使用! ,排除例外。
*.md !README*.md README-secret.md 所有.md 结尾的文件,但是不包含REME开头的.md文件,但README-secret.md 除外。README-secret.md 是包含的。
考虑一下:
*.md README-secret.md !README*.md 所有的.md结尾的文件,和README-secret.md文件。不包含以README开头的.md文件。即README-secret.md是不包含的。
类似于Linux中IPtables 规则的配置,是按照顺序来的。
FROM
FROM <image>
or
FROM <image>:<tag>
or
FROM <image>@<digest>
设置基础image。
MAINTAINER
MAINTAINER <name>
maintainer,指定制作这个image的作者。
RUN
两种形式
run 执行任何命令然后提交执行结果。已经提交执行结果的image在后面的步骤会被使用到。
使用反斜杠\ 用来将一个命令分两行写
RUN /bin/bash -c 'source $HOME/.bashrc;\ echo $HOME'
注意:
用户RUN指令的缓存在下一次构建期间不会自动失效。像RUN apt-get dist-upgrade -y 在缓存中则在下一次build也会被使用。
--no-cache,使缓存失效。
docker build --no-cache ADD指令也会使缓存失效
CMD
cmd有三种形式:
Dockerfile中只有最后一个CMD是起作用的。
CMD的最主要的目的就是为执行中的container提供默认参数。默认参数可以包含可执行的文件。
注意:
CMD作用就是在运行image时,设置一些同步运行的命令。
如果使用shell 形式,command将会在/bin/sh -c 下执行的
FROM ubuntu CMD echo "This is a test." | wc - 首选形式
FROM ubuntu CMD ["/usr/bin/wc","--help"]
如果在docker run 中指定参数,则会覆盖原来在CMD中默认指定的参数。
LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL 增加元数据到image。一个LABEL是键值对。
例子:
LABEL "com.example.vendor"="ACME Incorporated" LABEL com.example.label-with-value="foo" LABEL version="1.0" LABEL description="This text illustrates \ that label-values can span multiple lines." 每个LABEL都会产生一个layer,如果有很多layer的话可能会导致image不工作。 单个image layer
LABEL multi.label1="value1" multi.label2="value2" other="value3" 也可以是
LABEL multi.label1="value1" multi.label2="value2" other="value3" 如果原来已经存在的key,后面的 LABEL会使用新的覆盖。
查看image labels: docker inspect
EXPOSE
EXPOSE <port> [<port>...]
指定容器在运行的时候监听的端口
ENV
ENV <key> <value>
ENV <key1>=<value> <key2>=<value>...
设置环境变量<key> 值为<value>
更改环境变量
docker run --env <key>=<value>
ADD
add有两种形式
ADD命令从<src>复制文件 到 image文件系统的<dest>
每个<src>可以包含通配符,使用 filepath.Match原则进行匹配
ADD hom* /mydir/ # adds all files starting with "hom" ADD hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
<dest>是绝对路径或者是WORKDIR的相对路径。
ADD test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/ ADD test /absoluteDir/ # adds "test" to /absoluteDir/
所有的新文件和目录是被UID,GID 为0所创建的。即使root了。
如果<src>是远程URL文件,那么目标文件需要600权限
ADD 服从一下规则:
COPY
有两种形式:
COPY 从<src>复制新的文件或目录到容器的文件系统当中的<dest>
使用通配符进行匹配:
COPY hom* /mydir/ # adds all files starting with "hom" COPY hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
<dest>是绝对路径,或者相对WORKDIR的路径
COPY test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/ COPY test /absoluteDir/ # adds "test" to /absoluteDir/
所有的新文件和目录是被UID,GID 为0所创建的。即使root了。
COPY规则类似ADD
ENTRYPOINT
有两种形式:
ENTRYPOINT 允许你配置容器。
例子:
启动nginx使用其默认配置,监听端口80
docker run -i -t --rm -p 80:80 nginx
在Dockerfile中只有最新的ENTRYPOINT会生效。
exec 形式例子
使用entrypoint exec 形式设定那些默认不改变参数和命令,
使用CMD设定那些可能会改变的参数。
FROM ubuntu ENTRYPOINT ["top", "-b"] CMD ["-c"] shell 形式例子
FROM ubuntu
ENTRYPOINT exec top -b
cmd 和 entrypoint
VOLUME
VOLUME ["/data"]
volume 创建一个指定名字的挂载点,并将它作为本地或者其他容器的外部挂载的数据卷
docker run 用在基础image中被指定的本地已经存在的数据初始化新建的数据卷。
例子:
FROM ubuntu RUN mkdir /myvol RUN echo "hello world" > /myvol/greeting VOLUME /myvol 上面的 基础image中,/myvol 已经有数据文件greeting 此时又指定了 VOLUME 创建新的数据卷,
则将 greeting文件复制到新数据卷。
USER
USER daemon
WORKDIR
WORKDIR /path/to/workdir
可以多次被使用:
例子:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
pwd命令最终的输出结果,会是 /a/b/c
可以联合环境变量使用
例子:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
pwd命令最终的输出结果,是/path/$DIRNAME
ARG
ARG <name>[=<default value>]
ARG定义一个参数,使用用户在使用docker build 时可以传送到docker build 通过 --build-arg <varname>=<value>。
可以指定一个或多个
FROM busybox ARG user1 ARG buildno ... ARG有默认值,且在build时没值传给 docker build 则使用ARG 默认值。
ARG值在Dockerfile定义的时就已经生效,而不是在执行的时候。
例子:
1 FROM busybox 2 USER ${user:-some_user} 3 ARG user 4 USER $user... 通过这个Dcokerfile build
$ docker build --build-arg user=what_user Dockerfile 第二行USER 评估 some_user 作为 第三行 user参数的定义值。
第四行USER 认为从命令行传过来的 what_user 作为user参数的定义值。
在通过ARG指令定义之前,变量的任何使用都将导致空字符串。
ENVIRONMENT 参数定义会覆盖 同名的ARG定义:
1 FROM ubuntu 2 ARG CONT_IMG_VER 3 ENV CONT_IMG_VER v1.0.0 4 RUN echo $CONT_IMG_VER 通过这个Dockerfile build
$ docker build --build-arg CONT_IMG_VER=v2.0.1 Dockerfile
这个例子中,会使用v1.0.0 替代命令行传入的 v2.0.1.
这像是shell 脚本中 本地环境变量 会 替代 通过参数传入过来的环境变量。
build缓存的影响
ARG 变量不会作为环境变量持久化到image中。
然而它会在一些地方对build缓存存在一些影响。
如果Dockerfile定义了不同于之前build的 ARG 变量值时,缓存丢失会在第一次使用的时候出现,但值不是它原来的定义。
一般情况,在ARG 后立即接RUN,可以解决缓存丢失问题。
例子:两个Dockerfile
1 FROM ubuntu 2 ARG CONT_IMG_VER 3 RUN echo $CONT_IMG_VER 1 FROM ubuntu 2 ARG CONT_IMG_VER 3 RUN echo hello
在两个文件命令中,都在命令行指定CONT_IMG_VER 值,--build-arg CONT_IMG_VER =<value> 。
在指定的第2行都不会 产生 缓存丢失;在第3行会产生缓存丢失;
ARG CONT_IMG_VER会使RUN 这行被标识为与运行CONT_IMG_VER = <value> 和 echo hello相同,
如果<value> 改变,缓存便会丢失。
另一个例子:
1 FROM ubuntu 2 ARG CONT_IMG_VER 3 ENV CONT_IMG_VER $CONT_IMG_VER 4 RUN echo $CONT_IMG_VER 缓存丢失出现在了第三行,丢失原因是ENV参照ARG参数,然而这个参数在命令行被修改了。
ONBUILD
onbuild 在image中增加一个触发器,当这个image被作为其他image的基础image时,执行。
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
STOPSIGNAL
STOPSIGNAL signal
设置容器退出的 信号名称
HEALTHCHECK
两个形式:
告诉docker如何去检测容器是否仍然在工作。
options
状态值
例子:
HEALTHCHECK --interval=5m --timeout=3s \ CMD curl -f http://localhost/ || exit 1
总结
|
|
来自: WindySky > 《Dockerr入门》