官方文档地址:https://docs.docker.com/engine/reference/builder/
Dockerfile是一个文本格式的配置文件,其内容包含众多指令,用户可使用它快速的建立自定义镜像。linux
指令 | 做用 | 备注 |
---|---|---|
FROM | 指定基础镜像 | 任何Dockerfile中的第一条指令都必须是FROM 一个文件中能够存在多个FROM指令。 |
LABEL | 为镜像添加元数据标签信息。 | |
ARG | 定义建立镜像过程当中使用的变量,编译成功后不存在。 | 在运行docker build时,指定--builder-arg为变量赋值。 |
ENV | 设置环境变量 | 在镜像启动时也会存在。 docker run --env key=value 会覆盖同名变量 |
WORKDIR | 指定工做目录 | 可使用多个,建议使用绝对路径。 |
VOLUME | 建立数据卷挂载点 | 例如VOLUME ["/data/a","/data/b"] |
EXPOSE | 声明镜像内服务监听的端口 | 只起声明做用,不会自动完成映射。 |
USER | 指定运行容器时的用户名或ID | 后续RUN指令也会以这个用户身份运行。 |
STOPSIGNAL | 指定所建立镜像启动的容器接收退出的信号值 |
COPY src dst / ADD src dst
其相同点是:做用都是复制内容到镜像中;dst不存在时会建立;路径支持正则。
不一样点在于:golang
除了目的明确是要将一个URL或者tar文件做为src的状况下,其余状况推荐使用COPY。docker
CMD与ENTRYPOINT两种方式都支持,但推荐使用exec方式。shell
在任意一个Dockerfile下:ubuntu
finallyCommand = "" if exists(ENTRYPOINT) { finallyCommand = ENTRYPOINT if exists(dockerRunCommandParam){ // 情景一 finallyCommand += dockerRunCommandParam }elseif exists(CMD) { // 情景二。除了CMD指令自己,包括后面JSON数组全部 finallyCommand += CMDParams } // 情景三 }elseif exists(dockerRunCommandParam){ // 情景四 finallyCommand = dockerRunCommandParams }elseif exists(CMD){ // 情景五 finallyCommand = CMD }
总结起来一句话:有ENTRYPOINT,CMD和docker run指定的命令都做为参数追加到ENTRYPOINT的参数后;没有ENTRYPOINT,docker run指定了命令就执行,不然执行CMD(若是有的话)。数组
Dockerfile内容、构建镜像缓存
FROM alpine:latest ENTRYPOINT ["/bin/echo","entrypoint"] -> [feifei@ffmac.local] [~/work/docker] docker build -t test . // 情景三 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test entrypoint // 情景一 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test 12 34 entrypoint 12 34
Dockerfile添加CMD指令、构建镜像bash
FROM alpine:latest ENTRYPOINT ["/bin/echo","entrypoint"] CMD ["/bin/echo","cmd"] -> [feifei@ffmac.local] [~/work/docker] docker build -t test . // 情景二:CMD中的 "/bin/echo" 没有被当作命令执行,而是与"cmd"一块儿成为了ENTRYPOINT的参数。 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test entrypoint /bin/echo cmd
Dockerfile删除ENTRYPOINT指令、构建镜像app
FROM alpine:latest CMD ["/bin/echo","cmd"] -> [feifei@ffmac.local] [~/work/docker] docker build -t test . // 情景五 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test cmd // 情景四 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test echo 33 33
exec方式:RUN ["executable","param1","param2"]
shell方式:RUN command param1 param2
每条RUN指令将在当前镜像基础上执行指令,而且提交为新的镜像层。当命令较长时可使用\来换行ui
ONBUILD [INSTRUCTION]
做为父镜像被使用时自动执行的命令。对孙子镜像无效。可用于自动编译,检查等。
假如父镜像ParentImage的Dockerfile中有以下指令:
ONBUILD RUN mkdir /root/test
使用docker build基于ParentImage建立子镜像ChildImage的时候,会先执行ParentImage中的ONBUILD指令。等价于在ChildImage中添加了:
RUN mkdir /root/test
健康检查
HEALTHCHECK [OPTIONS] CMD command :根据执行命令返回值判断,0是成功,1是不健康。
HEALTHCHECK NONE :禁止健康检查
OPTIONS参数以下:
docker build [OPTIONS] PATH | URL | -
该命令默认读取指定路径下的Dockerfile(也可以使用 -f 指定),并将该路径下的全部数据做为上下文发送给Docker服务端。逐条执行指令,生成镜像。
通常状况下都须要使用FROM来指定父镜像,因此父镜像会影响到新生成镜像的大小和功能。
一般有两种镜像可做为父镜像:基础镜像和普通镜像(由第三方建立,基于基础镜像)。基础镜像通常是基于scratch或者Dockerfile中不存在FROM指令。
对于编译型语言一般须要编译环境和运行环境两个镜像:
app.go
package main import "fmt" func main() { fmt.Println("Hello World") }
Dockerfile中使用两次FROM
FROM golang:1.14-alpine as builder WORKDIR /go/src/test COPY app.go . RUN CGO_ENABLED=0 GOOS=linux go build -o app app.go FROM alpine:latest COPY --from=builder /go/src/test/app /root/ #此处 --from=builder 也能够改成 --from=0 CMD ["/root/app"]
构建、运行
-> [feifei@ffmac.local] [~/work/docker] docker build -t hello . -> [feifei@ffmac.local] [~/work/docker] docker run --rm hello Hello World
多阶段构建会生成编译环境镜像,也会将以前的同名镜像变为<none>:<none>
,清理此类镜像可执行如下命令:
docker rmi $(docker images --filter dangling=true -q)
COPY指令的--from选项也能够指定本地或者远程仓库的镜像
准备一个Dockerfile,内容是从ubuntu镜像中COPY一个文件到新镜像的/root/下
FROM alpine:latest COPY --from=ubuntu:latest /bin/bash /root/ CMD ["/bin/ls","/root/"]
dokcer build 构建镜像
-> [feifei@ffmac.local] [~/work/docker] docker build -t test . Sending build context to Docker daemon 19.46kB Step 1/3 : FROM alpine:latest ---> f70734b6a266 Step 2/3 : COPY --from=ubuntu:latest /bin/bash /root/ latest: Pulling from library/ubuntu d51af753c3d3: Pull complete fc878cd0a91c: Pull complete 6154df8ff988: Pull complete fee5db0ff82f: Pull complete Digest: sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7 Status: Downloaded newer image for ubuntu:latest ---> Using cache ---> 082f95ffaa69 Step 3/3 : CMD ["/bin/ls","/root/"] ---> Using cache ---> 76fa9d9a1abd Successfully built 76fa9d9a1abd Successfully tagged test:latest
dokcer run 运行镜像
-> [feifei@ffmac.local] [~/work/docker] docker run --rm test bash
.dockerignore
文件,避免发送没必要要的数据