由于构建Docker镜像的源码,是一个包含一些指令的文本文档,
指令大小写不明感,但是一般采用代写,
在Docker开始构建镜像时,Docker客户端会先在上下文目录中寻找.dockerignore文件,根据.dockerignore文件排除上下文目录中的部分文件和目录,然后把剩下的文件和目录传递给Docker服务端开始构建。“.dockerignore”语法与“.gitignore”相同。
${variablename:-word}:如果变量没有被设置,则采用“word”给其赋默认值,如果有则仍采用“variablename”本身的值。
$ echo ${NAME:-tom}
tom
$ NAME=jerry
$ echo ${NAME:-tom}
jerry
而 v a r i a b e l n a m e : + w o r d 则 与 {variabelname:+word}则与 variabelname:+word则与{variablename:-word}相反。
$ echo ${NAME:+tom}
tom
$ unset NAME
FROM指令是重要的一个且必须为Dockerfile文件开篇的第一行非注释行,用于为镜像文件构建过程中指定基础镜像,后续的指令运行与基础镜像所提供的运行环境
实践中,基础镜像可以是任何可用的镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会从Docker Hub Registry上拉取所需的镜像文件
如果找不到指定的镜像文件,docker build会返回一个错误信息。
Syntax
**FROM repository[:tag]**或
FROMrepository@digest
采用digest更为安全,指明哈希码。
注意此命令已废弃,但仍可使用,现在一般用“LABLE”。用于让Dockerfile制作者提供本人的详细信息,一般为邮箱等。
Dockerfile并不限制MAINTAINER指令可出现的位置,但一般推荐将其放置于FROM之后
Syntax
MAINTAINER
例如:MAINTAINER "gzr"[email protected]
kv键值对,例如:
LABLE MAINTAINER=“gzr [email protected]”
用于从Docker主机复制文件至创建的新镜像文件
Syntax
注意:在路径中有空白字符时,通常使用第二种格式
文件复制准则
ADD指令类似于COPY指令,ADD支持使用TAR文件和URL路径
Syntax
注意:在路径中有空白字符时,通常使用第二种格式
操作准则
同COPY指令
如果src为URL,且dest不以/结尾,则src指定的文件将被下载并直接被创建为dest;
如果dest以 / 结尾,则文件名URL指定的文件将被直接下载并保存为dest / filename
如果src是一个本地系统上的压缩格式的tar文件,它将展开为一个目录,其行为类似于"tar -x"命令;然而,通过URL获取到的tar文件将不会自动展开;
如果src有多个,或其间接或直接使用了通配符,则dest必须是一个以 / 结尾的目录路径;如果dest不以 / 结尾,则将其视作一个普通文件,src的内容将被直接写入到dest。
# Dockerfile test
FROM busybox:latest
MAINTAINER gzr <[email protected]>
COPY test.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/nginx-1.16.0.tar.gz /usr/local/src/
# 创建镜像
$ docker build -t tinyhttpd:v0.1-3 ./
$ docker run --name tinyweb1 --rm tinyhttpd:v0.1-3 ls /usr/local/src
nginx-1.16.0.tar.gz
# 如上,说明压缩包并没有打开。
# 如果把需要使用的压缩包事先下载到本地,则会解压目录,在Dockerfile中增加如下指令
ADD nginx-1.16.0.tar.gz /usr/local/src
# 然后重新创建镜像
$ docker run --name tinyweb1 --rm tinyhttpd:v0.1-4 ls /usr/local/src
nginx-1.16.0
$ docker run --name tinyweb1 --rm tinyhttpd:v0.1-4 ls /usr/local/src/nginx-1.16.0
CHANGES
CHANGES.ru
LICENSE
README
auto
conf
configure
contrib
html
man
src
# 如上,可以发现nginx的tar包已经自动解压了。
WORKDIR dirpath
例如
WORKDIR /var/log
WORKDIR $STATEPATH
# 在Dockerfile中加入如下行
VOLUME /data/mysql/
$ docker build -t tinyhttpd:v0.1-5 ./
$ docker run --name tinyweb1 --rm tinyhttpd:v0.1-5 sleep 60
$ docker inspect tinyweb1| grep Destination
"Destination": "/data/mysql"
# 即使Dockerfile中指定了暴露端口,仍然需要暴露在命令行加入-P端口暴露给宿主机
$ docker run --name tinyweb1 --rm -P tinyhttpd:v0.1-6 /bin/httpd -f -h /data/web/html
# 在Dockerfile中增加如下内容:
ENV DOC_ROOT /data/web/html/
COPY test.html ${DOC_ROOT:-/data/web/html/}
# 也可以在将镜像初始化为容器,在命令行中注入环境变量采用-e或者,--env
$ docker run --name tinyweb1 --rm -P -e WEB_SERVER_PACKAGE="nginx-1.15.2" tinyhttpd:v0.1-7 printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=6508bf3524f6
WEB_SERVER_PACKAGE=nginx-1.15.2
DOC_ROOT=/data/web/html/
HOME=/root
# 在Dockerfile中添加以下内容:
FROM busybox
LABEL maintainer="gzr " app="httpd"
ENV WEB_DOC_ROOT="/data/web/html"
RUN mkdir -p $WEB_DOC_ROOT && \
echo 'Busybox httpd server.
' > ${WEB_DOC_ROOT}/index.html
` CMD /bin/httpd -f -h ${WEB_DOC_ROOT}`
$ docker build -t tinyhttpd:v0.2-1 .
$ docker image inspect tinyhttpd:v0.2-1
"Cmd": [
"/bin/sh",
"-c",
"/bin/httpd -f -h ${WEB_DOC_ROOT}"
]
# 上述输出内容表示,调用了shell
$ docker exec -it tineweb2 /bin/sh
/ # ps
PID USER TIME COMMAND
1 root 0:00 /bin/httpd -f -h /data/web/html
7 root 0:00 /bin/sh
13 root 0:00 ps
# 然而在Dockerfile增加此行,则会报错
CMD ["/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
$ docker run -it --name tinyweb2 --rm -P tinyhttpd:v0.2-2
httpd: can't change directory to ' ${WEB_DOC_ROOT}': No such file or directory
failed to resize tty, using default size
# 这是因为它默认不会启动为shell的子进程。
是使镜像启动为容器时,默认调用的命令。CMD是只能有一个有效。
# 在Dockerfile中增加如下行内容
ENTRYPOINT /bin/httpd -f -h ${WEB_DOC_ROOT}
$ docker build -t tinyhttpd:v0.2-5 .
$ docker run -it --name tinyweb2 --rm -P tinyhttpd:v0.2-5
# 然而执行如下命令,相当于在ENTRYPOINT末尾增加ls /data/web/html/命令。有可能执行不了,需要采用--entrypoint参数来指定。
$ docker run -it --name tinyweb2 --rm -P tinyhttpd:v0.2-5 ls /data/web/html/
# 类似于下述的描述,加入--entrypoint 此时的ls是覆盖了CMD
$ docker run -it --name tinyweb2 --rm -P --entrypoint "ls /data/web/html/" tinyhttpd:v0.2-5
如果CMD和ENTRYPOINT同时定义了,CMD命令结果会被作为传递给ENTRYPOINT。
注意:JSON数组中,要使用双引号。
这是一个健康检查命令,用来检查容器启动运行时是否正常,若正常则返回healthy,否则返回unhealthy,例如有时候服务器被卡在无限循环中,并且无法处理新连接的情况,即使服务器进程仍在运行,但实际上问题已经产生了却不会报错,因为从docker看来这个容器还在运行,添加这个心跳检查命令,可以隔一段时间检查容器是否正常运行。
Syntax
通过在容器中运行命令来检查容器运行状况。
HEALTHCHECK [OPTIONS] CMD command
禁用从基本映像继承的任何运行状况检查
HEALTHCHECK NONE
参数有以下4个:
结果有3种:
在docker构建过程中,会默认使用/bin/sh作为shell环境,Windows下构建默认使用cmd作为shell环境,但有时候我们需要其他shell环境来执行RUN的内容,这时需要用SHELL命令提醒Docker更换shell环境。
Syntax
默认在Linux下是:["/bin/sh","-c"],在Windows下是[“cmd”,"/S","/C"]
例如在Windows下降powershell更换为默认shell环境:
SHELL [“powershell”, “-command”]
STOPSIGNAL允许用户定制化允许docker stop时的信号。
Syntax
STOPSIGNAL signal
例如:STOPSIGNAL SIGKILL,这样构建的镜像其启动的容器在停止时会发送SIGKILL信号,这个命令适用于一些不能接受正常退出信号的容器。
ARG命令定义一个变量,用户可以在构建时使用,效果和docker build --build-arg =一样,可以在构建时设定参数,这个参数只会在构建时存在。
Syntax
ARG name[=default value]
ARG与ENV类似,不同的是ENV会在镜像构建结束之后仍然存在镜像中,而ARG在镜像构建之后消失,例如在构建过程中,如果希望整个构建过程是无交互的,那么可以设置如下ARG命令(仅限Debian)
ARG DEBIAN_FRONTEND=noninteractive
# 或者在构建过程中修改作者信息
ARG author= "gzr "
LABEL maintainer=${author}
$ docker build --build-arg author="gezr17 " -t myweb:v0.3-9 .