WORKDIR dirpath
示例:
- WORKDIR /usr/local
- ENV
用于为镜像定义所需的环境变量, 并可被 Dockfile 中位于其以后的指令所调用, 如 ADD,COPY,RUN 等调用格式为 $variable_name 或者 ${variable_name}, 此外在启动容器时候这些变量也是存在的.
语法:
- ENV <key> <value>
- ENV <key>=<value> ...
注意:
第一种格式中 key 之后的所有值会被作为 value, 因此一次只能设置一个变量
第二种格式可一次性设置多个变量, 每个变量为一个 key=value 的键值对, 如果 value 种包含空格, 可以用反斜线 (\) 转义, 也可以通过对 value 加引号进行标识, 此外反斜线也可用于续行, 多个变量时候建议使用.
示例:
- ENV myName="John Doe" \
- myDog=Rex \
- myCat=fluffy
- ENV myCat fluffy
- RUN
用于在 build 过程中运行的程序, 可以是任何指令, 可以指定多个 RUN
语法:
- RUN <command> #shell 格式默认 Linux 采用 / bin/sh -c,Windows 采用 cmd /S /C
- RUN ["executable", "param1", "param2"] #可执行程序格式
示例:
- RUN yum install -y nginx
- RUN ["/bin/bash", "-c", "echo hello"]
- EXPOSE
用于为容器暴露端口到外部, 用于实现通讯, 类似于 docker run 的 - p 选项
语法:
EXPOSE <port> [<port>/<protocol>...]
解释:
port: 端口
protocol: 协议, 可以是 udp 或 tcp, 默认 tcp
示例:
- EXPOSE 8080
- EXPOSE 8080/udp 8088/tcp
- VOLUME
用于在 image 中创建一个挂载目录, 以挂载宿主机上的目录
语法:
- VOLUME <path>
- VOLUME ["path"]
解释:
path: 代表容器中的目录, 与 docker run 不同, Dockerfile 中不能指定宿主机目录, 默认使用 docker 管理的挂载点
示例:
- VOLUME ["/var/log/"]
- VOLUME /myvol
- CMD
用于为在镜像启动为容时候提供的默认命令, 该指定可以有多个, 但是只有最后一个生效.
语法 :
- CMD command param1 param2 #shell 格式, 含有 shell 环境
- CMD ["executable","param1","param2"] #可执行程序格式
- CMD ["param1","param2"] #第三种用于为 ENTRYPOINT 提供默认参数
注意:
在第一种格式中 command 通常是一个 shell 命令, 且默认以 / bin/sh -c 来运行它, 这意味着此进程在容器的的 PID 不为 1, 不能接受 unix 信号, 因此使用 docker stop <container > 命令停止容器时, 此进程接受不到 SIGTERM 信号.
第二种格式是可执行程序运行方式, 不会以 "/bin/sh -c" 来发起, 无 shell 环境, 所有 shell 变量不能引用, 但是可以用 "/bin/bash -c" 作为启动命令达到第一种格式效果
第三种格式需要结合 ENTRYPOINT 使用, 作用是为其提供默认参数
ENTRYPOINT
类似于 CMD 功能, 用于为启动容器指定默认启动命令, 与 CMD 不同的是 ENTRYPOINT 命令不会随着 docker run 后使用的命令覆盖而会把命令作为参数, 除非 docker run 参数中指定了 - entrypoint
语法 :
- ENTRYPOINT <command>
- ENTRYPOINT ["<executable>", "<param1>", "<param2>"]
注意事项:
与 CMD 类似, 第一种方式默认会以 / bin/sh -c 启动, 而第二种则不会, 也就意味着没有 shell 环境
通常 ENTRPOINT 用于使用 ENTRPOINT 脚本启动
当 CMD 与 ENTRYPOINT 同时存在时, CMD 的参数为 ENTRYPOINT 提供
示例:
- ["nginx","-g","daemon off"]
- USER
用于指定构建镜像时 RUN,CMD,ENTRYPOINT 等指令使用的用户或 UID, 默认情况容器运行身份为 ROOT
语法 :
- USER <user>[:<group>]
- USER <UID>[:<GID>]
注意事项:
指定的 USER 或者 GROUP 必须在容器中存在, 否则指令会运行失败
示例:
- USER nginx
- STOPSIGNAL
该指令用于设置容器停止时向容器内进程发送的信号, 列如 9 ,SIGKILL,SIGTERM.
语法:
STOPSIGNAL signal
示例:
STOPSIGNAL SIGKILL
注意事项:
向容器发送信号只能被 PID=1 的进程所接收, 当 PID=1 进程不是应用进程时候, 应用进程收不到终止信号.
HEALTHCHECK
该指令在 1.12 版本中添加, 用于对容器中的应用进行健康检查, 不做检查使用 NONE. 当对容器做了健康检查时候, 检查值为 0 表示成功, 非 0 表示不健康.
语法:
HEALTHCHECK [OPTIONS] CMD command
其中 OPTIONS 有如下选项:
--interval=DURATION 检查间隔(默认: 30s)
--timeout=DURATION 超时时间(默认 t: 30s)
--start-period=DURATION 等待检查的时间, 默认 0s 代表一启动就检查 (默认: 0s)
--retries=N (default: 3) 重试次数
示例:
- HEALTHCHECK --interval=5m --timeout=3s \
- CMD curl -f http://localhost/ || exit 1
- SHELL
将可执行程序运行为 shell 环境, 默认以 / bin/sh -c 运行
语法:
SHELL ["executable", "parameters"]
示例:
- SHELL ["echo", "hello"] #等价于 RUN echo hello
- ARG
该指令用于在 build 过程中提供参数, 而在命令行使用 --build-arg <varname>=<value > 来传递参数值, 这样可以使用参数进行构建镜像.
语法:
ARG <name>[=<default value>]
示例:
- Dockerfile
- FROM nginx
- ARG CONF="/tmp/nginx.conf"
- LABEL Author=wd
- RUN touch "${CONF}"
构建镜像:
- [root@app51 ~]# docker build --build-arg CONF='/etc/test.conf' -t nginx:v15.2 ./
- Sending build context to Docker daemon 225.6MB
- Step 1/4 : FROM nginx
- ---> f09fe80eb0e7
- Step 2/4 : ARG CONF="/tmp/nginx.conf"
- ---> Using cache
- ---> ac081589c644
- Step 3/4 : LABEL Author=wd
- ---> Using cache
- ---> 53b9b0ba4460
- Step 4/4 : RUN touch "${CONF}"
- ---> Running in 50debe96f876
- Removing intermediate container 50debe96f876
- ---> d8680a2433bc
- Successfully built d8680a2433bc
- Successfully tagged nginx:v15.2
运行容器查看:
- [root@app51 ~]# docker run --rm nginx:v15.2 ls /etc/test.conf -l
- -rw-r--r-- 1 root root 0 Feb 27 11:18 /etc/test.conf
- ONBULD
用于在 Dockerfile 中定义一个触发器, 当制作出来的镜像被别人用于基础镜像时候自动触发.
语法:
ONBUILD [INSTRUCTION]
解释:
INSTRUCTION: 指令可以是 RUN ,COPY 等
注意事项:
ONBUILD 不会触发 FROM 指令.
在镜像标签中应明确指出 onbuild 关键字, 以标记使用其基础镜像会触发其他指令
示例:
- ONBUILD ADD . /App/src
- ONBUILD RUN /usr/local/bin/python-build --dir /App/src
四, 使用 multi-stage
在构建镜像过程中, 我们可能只需要某些镜像的产物, 比如在运行一个 go 程序需要先 go 程序包编译后才运行, 如果在一个镜像里面完成, 先要经过安装编译环境, 程序编译完再安装运行环境, 最后运行程序, 这样的镜像体积往往比较大, 不利于我们使用. 而真正我们需要的镜像是只有程序包和运行环境, 编译环境的构建在运行容器时候是不需要的, 所以 Docker 提供了一种解决方案就是 multi-stage(多阶段构建).
Docker 允许多个镜像的构建可以使用同一个 Dockerfile, 每个镜像构建过程可以称之为一个 stage, 简单理解就是一个 FROM 指令到下一个 FROM 指令, 而每个 stage 可使用上一个 stage 过程的产物或环境(其实还支持其他镜像的), 这样一来, 最终所得镜像体积相对较小. 不仅如此多阶段构建同样可以很方便地将多个彼此依赖的项目通过一个 Dockerfile 就可轻松构建出期望的容器镜像, 而不用担心镜像太大, 项目环境依赖等问题.
通过上述介绍, 我们可以在第一个 stage 将 go 程序编译得到编译后程序包, 然后在第二个 stage 中直接拷贝编译好的 go 程序包到运行环境中, 最后的镜像中就只有程序包和运行环境. 以下作为示例:
- FROM golang:1.7.3
- WORKDIR /go/src/GitHub.com/alexellis/href-counter/
- RUN go get -d -v golang.org/x.NET/html
- COPY App.go .
- RUN CGO_ENABLED=0 GOOS=Linux go build -a -installsuffix cgo -o App .
- FROM alpine:latest
- RUN apk --no-cache add ca-certificates
- WORKDIR /root/
- COPY --from=0 /go/src/GitHub.com/alexellis/href-counter/App .
- CMD ["./app"]
在以上 Dockerfile 中存在两个 FROM 指令, 也就是两个 stage, 第一个 stage 用于构建产物, 而在第二个 stage 中使用 COPY --from=0 意思将第一个 stage 中的 / go/src/GitHub.com/alexellis/href-counter/App 拷贝到. 目录, 第二个 stage 仅仅相当于执行 copy 就有了构建产物, 不用在安装编译环境, 镜像会很缩小.
命名 stage
默认情况下, stage 未命名, 可以通过整数来引用它们, 第一个 stage 表示 0, 第二个表 1 以此类推. 但是, 当有多个 stage 时候, 这样会显得麻烦, Docker 提供 AS 语法可以为 stage 命名:
FROM golang:1.7.3 as builder
然后在另一个 stage 中使用:
COPY --from=builder /go/src/GitHub.com/alexellis/href-counter/App .
使用本地 stage
除了可以使用 Dockerfile 中的 stage 外, 构建镜像时候还可以直接使用本地已存在的环境和产物, 例如:
COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf
构建镜像建议
基础镜像尽量选择比体积较小的镜像, 如每个官方发行的 alpine 镜像. 虽然这版本镜像比较小, 但是与之带来的是利用该类镜像运行的容器中排错的命令很少;
使用 RUN 指令时候, 尽量把多个 RUN 指令合并为一个, 通常做法是使用 && 符号;
通过 multi-stage 方法减少一些不必要使用的环境来减小镜像;
安装完成软件同时删除一些不需要的文件或目录;
ref:
《Dockerfile reference》 https://docs.docker.com/engine/reference/builder/
《Use multistage builds》
来源: https://www.cnblogs.com/wdliu/p/10469257.html