用法
docker build -t 镜像名:标签 .
# 用来指定Dockerfile地址,如果执行此命令所在目录就是Dockerfile目录,则可以省略
-f /etc/Dockerfile
# 可以指定构建多个镜像
-t 镜像名:标签1 -t 镜像名:标签2
Windows情况
- 错误
1
2
3FROM microsoft/nanoserver
COPY testfile.txt c:\\
RUN dir c:\ - 正常
1
2
3
4
5# escape=`
FROM microsoft/nanoserver
COPY testfile.txt c:\
RUN dir c:\环境替换
$variable_name
或${variable_name}
表达意思一致,但是大括号可以用来表示拼接${foo}_bar
${variable_name}
语法支持bash
指定的一些标准修饰符${variable:-word}
表示如果variable
设置,则结果为该值.未设置则为word
${variable:+word}
表示如果variable
设置,则结果为word
.未设置则为空字符串
- 转义
\
例如\$foo
或\${foo}
将分别转换为$foo
和${foo}
字符串 不会是变量1
2
3
4
5FROM busybox
ENV foo /bar
WORKDIR ${foo} # WORKDIR /bar
ADD . $foo # ADD . /bar
COPY \$foo /quux # COPY $foo /quux - 在
Dockerfile
支持的关键词ADD
COPY
ENV
EXPOSE
FROM
LABEL
STOPSIGNAL
USER
VOLUME
WORKDIR
ONBUILD
当与上面支持的一个指令结合使用时
.dockerignore文件
除了README.md
所有的.md
文件都忽略
1 | *.md |
temp?
匹配根目录下的/tempa
或/tempb
被忽略*/temp*
表示/somedir/temporary.txt
或/somedir/temp
被忽略*/*/temp*
表示/somedir/subdir/temporary.txt
被忽略
FROM
1 | FROM 镜像名:标签 |
指定基本镜像,放在第一行
可以多次出现,创建多个镜像,也可以在一个镜像继续构建镜像
RUN
将长的复杂的
RUN
尽可能使用\
反斜杠分割,提高可读性
如果指定了apt-get
更新失败,因为有RUN
指令缓存,可以使用指定版本号进行更新
1 | RUN apt-get update && apt-get install -y \ |
如果失败,执行另外一个命令
1 | 如果`wget -O - https://some.site`失败 就执行`wc -l > /number` |
这里的命令为Shell
命令,默认是Linux的/bin/sh -c
或cmd /S /C
Windows
1 | RUN 命令 |
exec
形式
1 | RUN ["executable", "param1", "param2"] |
可以使用\
来继续到下一行,下面两者相等
1 | RUN /bin/bash -c 'source $HOME/.bashrc; \ |
如果想用/bin/sh
以外的形式,使用exec
形式,这里需要使用双引号,因为exec
形式会解析为JSON数组
例如RUN ["/bin/bash", "-c", "echo hello"]
对于exec
形式RUN [ "echo", "$HOME" ]
不会进行变量替换,可以使用RUN [ "sh", "-c", "echo $HOME" ]
对于JSON形式必须转义\
反斜杠.
在Windows中\
反斜杠是路径分隔符RUN ["c:\windows\system32\tasklist.exe"]
执行异常RUN ["c:\\windows\\system32\\tasklist.exe"]
执行正常
对于RUN
指令,下一次构建继续生效.
可以使用--no-cache
来对RUN
指令缓存失效docker build --no-cache
CMD
CMD ["executable","param1","param2"]
这是首选的exec
形式CMD ["param1","param2"]
作为ENTRYPOINT
的默认参数CMD command param1 param2
这是shell
形式
支持这三种形式,但在Dockerfile
中只支持最后一条CMD
命令生效exec
形式会解析为JSON数组,因此需要使用双引号
运行容器docker run ...
会覆盖CMD
指令
LABEL
两种效果相同,可以使用多个LABEL
标签来标注信息,但最好合并为一个
1 | LABEL multi.label1="value1" multi.label2="value2" other="value3" |
使用双引号或者使用\
反斜杠转义
1 | LABEL vendor1="ACME Incorporated" |
MAAINAINER 已弃用
被LABEL
灵活替代LABEL maintainer="mritd <mritd@linux.com>"
EXPOSE
可以指定向外暴露端口
也可以指定协议TCP
还是UDP
默认TCP
EXPOSE 80/udp
指定UDP
协议的80
端口
要同时在TCP和UDP上公开,请包括以下两行
1 | EXPOSE 80/tcp |
运行它们使用-p
来覆盖docker run -p 80:80/tcp -p 80:80/udp ...
ENV
1 | ENV key value |
第一种形式,只能设置一个值key
后面空格 后面的全部值都视为字符串value
的值,包括空格
第二种形式,可用于反斜杠 双引号
例如 下面两种相同
1 | ENV myName="John Doe" myDog=Rex\ The\ Dog \ |
运行容器时可以使用docker run --env key=value...
来改变
ADD
1 | ADD Linux路径 容器路径 |
复制文件到镜像中ADD hom* /mydir/
# 表示以hom
开头的所有文件ADD hom?.txt /mydir/
# 表示复制一个字符,例如home.txt
后面一个路径是绝对路径或相对WORKDIR
的路径ADD test relativeDir/
添加到WORKDIR/relativeDir/
ADD test /absoluteDir/
添加到/absoluteDir/
ADD arr[[]0].txt /mydir/
添加arr[0].txt
注意事项:
Linux路径
如果是目录,则容器路径
也是目录,斜杠结尾,复制后容器路径/Linux路径
Linux路径
直接或由于使用通配符而指定了多个资源,则容器路径
必须是目录,并且必须以/
斜杠结尾容器路径
不以斜杠结尾,则将其视为常规文件,并将其内容Linux路径
写入容器路径
容器路径
不存在,它将与路径中所有缺少的目录一起创建
COPY
同上
1 | COPY Linux路径 容器路径 |
ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"]
这是首选的exec
形式ENTRYPOINT command param1 param2
这是shell
形式
会覆盖所有的CMD
指令,只有最后一条ENTRYPOINT
生效
也可以在容器运行时覆盖docker run --entrypoint
如果想用/bin/sh
以外的形式,使用exec
形式,这里需要使用双引号,因为exec
形式会解析为JSON数组
例如ENTRYPOINT ["/bin/bash", "-c", "echo hello"]
对于exec
形式ENTRYPOINT [ "echo", "$HOME" ]
不会进行变量替换,可以使用ENTRYPOINT [ "sh", "-c", "echo $HOME" ]
VOLUME
1 | exec形式 |
如果已经是容器卷
,再次构建更改了这个容器卷
,更改将不生效
USER
1 | USER <user>[:<group>] |
该USER
指令设置运行映像时以及用于任何映像时使用的用户名(或UID)和可选的用户组(或GID)
ARG
指定一个变量
通常使用ARG
或ENV
来指定变量供RUN
使用
同名情况下ENV
会覆盖ARG
的变量
例如
1 | FROM alpine:3.7 |
WORKDIR
1 | WORKDIR /path/to/workdir |
用来指定工作目录
1 | WORKDIR /a |
1 | ENV DIRPATH /path |
Dockerfile实例
1 | # Nginx |
1 | # Firefox over VNC |
1 | # Multiple images example |