docker 实践六:dockerfile 详解

本篇开始来学习关于 dockerfile 的知识。

注:环境为 CentOS7,docker 19.03。

dockerfile 是⼀个⽂本格式的配置⽂件, ⽤户可以使⽤ dockerfile 来快速创建⾃定义的镜像。

指令系统

dockerfile 主要是通过一个指令来实现想要的功能的。dockerfile 支持的指令如下

ARG

定义创建镜像过程中使⽤的变量。格式为:

ARG<name>[=<default value>]

在执⾏docker build时, 可以通过 -build-arg[=] 来为变量赋值。 当镜像编译成功后, ARG指定的变量将不再存在(ENV指定的变量将在镜像中保留)。

Docker内置了⼀些镜像创建变量, ⽤户可以直接使⽤⽽⽆须声明, 包括(不区分⼤⼩写) HTTP_PROXY、 HTTPS_PROXY、 FTP_PROXY、NO_PROXY。`

FROM busybox
ARG user1
ARG buildno=1
USER &user1
...

注:不要使用构建时变量来传递 github 密钥,用户凭据等重要信息。使用 docker history 命令可以查看构建时的变量信息。

FROM

指定所创建镜像的基础镜像。格式为:

  • FROM[AS ]
  • FROM [AS ]
  • FROM@ [AS ]

任何 dockerfile中 第⼀条指令必须为FROM指令。 并且, 如果在同⼀个 dockerfile 中创建多个镜像时, 可以使⽤多个FROM指令(每个镜像⼀次)。
为了保证镜像精简, 可以选⽤体积较⼩的镜像如Alpine或Debian作为基础镜像。 例如:

ARG VERSION=9.3
FROM debian:${VERSION}

LABEL

LABEL指令可以为⽣成的镜像添加元数据标签信息。 这些信息可以⽤来辅助过滤出特定镜像。格式为 LABEL<key>=<value><key>=<value><key>=<value>

LABEL version="1.0.0-rc3"
LABEL author="yeasy@github" date="2020-01-01"
LABEL description="This text illustrates \
    that label-values can span multiple lines."

EXPOSE

声明镜像内服务监听的端口。格式为 EXPOSE<port>[<port>/<protocol>...]

EXPOSE 22 80 8443/udp

注意该指令只是起到声明作⽤, 并不会⾃动完成端⼜映射

ENV

指定环境变量, 在镜像⽣成过程中会被后续RUN指令使⽤, 在镜像启动的容器中也会存在。格式为ENV<key><value>ENV<key>=<value>...

ENV APP_VERSION=1.0.0
ENV APP_HOME=/usr/local/app
ENV PATH $PATH:/usr/local/bin

指令指定的环境变量在运⾏时可以被覆盖掉, 如docker run --env <key>=<value> built_image。注意当⼀条ENV指令中同时为多个环境变量赋值并且值也是从环境变量读取时, 会为变量都赋值后再更新。

ENTRYPOINT

指定镜像的默认⼊⼜命令, 该⼊⼜命令会在启动容器时作为根命令执⾏, 所有传⼊值作为该命令的参数。⽀持两种格式:

  • ENTRYPOINT["executable", "param1", "param2"]: exec调⽤执⾏;
  • ENTRYPOINT command param1 param2: shell中执⾏。

此时, CMD指令指定值将作为根命令的参数。每个Dockerfile中只能有⼀个ENTRYPOINT, 当指定多个时, 只有最后⼀个起效。在运⾏时, 可以被 --entrypoint 参数覆盖掉, 如 docker run--entrypoint

VOLUME

创建⼀个数据卷挂载点。格式为 VOLUME["/data"]
运⾏容器时可以从本地主机或其他容器挂载数据卷, ⼀般⽤来存放数据库和需要保持的数据等。

USER

指定运⾏容器时的⽤户名或UID, 后续的RUN等指令也会使⽤指定的⽤户⾝份。格式为 USER daemon

当服务不需要管理员权限时, 可以通过该命令指定运⾏⽤户, 并且可以在Dockerfile中创建所需要的⽤户。 例如:

RUN groupadd -r postgres && useradd --no-log-init -r -g postgres postgres

要临时获取管理员权限可以使⽤gosu命令。

WORKDIR

为后续的RUN、 CMD、 ENTRYPOINT指令配置⼯作⽬录。格式为 WORKDIR/path/to/workdir

可以使⽤多个WORKDIR指令, 后续命令如果参数是相对路径, 则会基于之前命令指定的路径。 例如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

则最终路径为/a/b/c。

注:为了避免出错, 推荐WORKDIR指令中只使⽤绝对路径。

ONBUILD

指定当基于所⽣成镜像创建⼦镜像时, ⾃动执⾏的操作指令。格式为 ONBUILD [INSTRUCTION]

例如, 使⽤如下的Dockerfile创建⽗镜像ParentImage, 指定 ONBUILD 指令:

# Dockerfile for ParentImage[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

使⽤ docker build 命令创建⼦镜像 ChildImage 时(FROM ParentImage),会⾸先执⾏ParentImage中配置的ONBUILD指令:

# Dockerfile for ChildImage
FROM ParentImage

等价于在 ChildImage 的 dockerfile 中添加了如下指令:

#Automatically run the following when building ChildImage
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src
...

由于ONBUILD指令是隐式执⾏的, 推荐在使⽤它的镜像标签中进⾏标注, 例如ruby: 2.1-onbuild。

ONBUILD指令在创建专门⽤于⾃动编译、 检查等操作的基础镜像时,⼗分有⽤。

STOPSIGNAL

指定所创建镜像启动的容器接收退出的信号值:

STOPSIGNAL signal

HEALTHCHECK
配置所启动容器如何进⾏健康检查(如何判断健康与否),⾃ docker1.12 开始⽀持。
格式有两种:

  • HEALTHCHECK[OPTIONS]CMD command: 根据所执⾏命令返回是否为0来判断;
  • HEALTHCHECK NONE: 禁⽌基础镜像中的健康检查。

OPTION⽀持如下参数:
-- -interval=DURATION(default: 30s): 过多久检查⼀次;

  • --timeout=DURATION(default: 30s): 每次检查等待结果的超时;
  • --retries=N(default: 3): 如果失败了, 重试⼏次才最终确定失败

SHELL

指定其他命令使⽤ shell 时的默认 shell 类型:

SHELL `["executable", "parameters"]` 

默认值为 ["/bin/sh", "-c"]

对于Windows系统,Shell路径中使⽤了“”作为分隔符, 建议在 dockerfile 开头添加 #escape='来指定转义符。

RUN

运⾏指定命令。格式为

  • RUN
  • RUN ["executable", "param1", "param2"]。

注意后者指令会被解析为 JSON 数组, 因此必须⽤双引号。 前者默认将在shell终端中运⾏命令, 即/bin/sh-c; 后者则使⽤exec执⾏, 不会启动shell环境。

指定使⽤其他终端类型可以通过第⼆种⽅式实现, 例如RUN ["/bin/bash", "-c", "echo hello"]

每条RUN指令将在当前镜像基础上执⾏指定命令, 并提交为新的镜像层。 当命令较长时可以使⽤\来换⾏。 例如:

RUN apt-get update \
    && apt-get install -y libsnappy-dev zlib1g-dev libbz2-dev \
    && rm -rf /var/cache/apt \
    && rm -rf /var/lib/apt/lists/*

CMD

CMD 指令⽤来指定启动容器时默认执⾏的命令。
⽀持三种格式:

  • CMD["executable", "param1", "param2"]: 相当于执⾏ executableparam1 param2, 推荐⽅式;
  • CMD command param1 param2: 在默认的Shell中执⾏, 提供给需要交互的应⽤;
  • CMD["param1", "param2"]: 提供给ENTRYPOINT的默认参数。

每个 Dockerfile 只能有⼀条CMD命令。 如果指定了多条命令, 只有最后⼀条会被执⾏。如果⽤户启动容器时候⼿动指定了运⾏的命令(作为run命令的参数) , 则会覆盖掉CMD指定的命令。

ADD

添加内容到镜像。格式为 ADD <src> <dest>

该命令将复制指定的 路径下内容到容器中的 路径下。其中 可以是Dockerfile所在⽬录的⼀个相对路径(⽂件或⽬录);也可以是⼀个URL; 还可以是⼀个tar⽂件(⾃动解压为⽬录) 可以是镜像内绝对路径, 或者相对于⼯作⽬录(WORKDIR) 的相对路径。

路径⽀持正则格式, 例如:

ADD *.c /code/

COPY

复制内容到镜像。格式为 COPY <src> <dest>

复制本地主机的 (为Dockerfile所在⽬录的相对路径, ⽂件或⽬录) 下内容到镜像中的 。 ⽬标路径不存在时, 会⾃动创建。路径同样⽀持正则格式。

COPY与ADD指令功能类似, 当使⽤本地⽬录为源⽬录时, 推荐使⽤COPY。

创建镜像

创建镜像使用命令 docker [image] build, 格式为 docker build [OPTIONS] PATH | URL| -

该命令将读取指定路径下(包括⼦⽬录) 的Dockerfile, 并将该路径下所有数据作为上下⽂(Context) 发送给Docker服务端。 Docker服务端在校验Dockerfile格式通过后, 逐条执⾏其中定义的指令, 碰到ADD、 COPY和RUN指令会⽣成⼀层新的镜像。 最终如果创建镜像成功, 会返回最终镜像的ID。

docker build 支持以下的选项:

猜你喜欢

转载自www.cnblogs.com/xingyys/p/11405501.html