基本结构
第一类
基于Dockerfile中指令的用途和它们在构建过程中所扮演的角色
基础镜像指定:
指令:FROM
解释:
这行告诉Docker使用哪个已有的镜像作为基础,你的新镜像将基于这个基础镜像进行构建。可以想象成是在说:“嘿,Docker,我需要一个空白的画布来画画,这个画布就是我指定的基础镜像。”
环境设置:
指令:ENV, LABEL, ADD, COPY, WORKDIR
解释:
这些指令用来设置镜像中的环境变量、添加元数据、复制文件到镜像中以及设置工作目录。就像在画布上画上背景、添加装饰,为应用的运行搭建舞台。
应用依赖安装:
指令:RUN
解释:
RUN 指令用于执行命令,通常用来安装应用所需的依赖。这就好比在舞台上布置道具和设备,确保应用可以正常运行。
应用配置和启动:
指令:CMD, ENTRYPOINT, EXPOSE, VOLUME, USER
解释:
CMD 和 ENTRYPOINT:这两个指令定义了容器启动时执行的命令。可以想象成是定义了舞台上的演员和他们的动作。
EXPOSE:声明容器运行时监听的端口,就像告诉观众,通过哪个窗口可以看到舞台上的表演。
VOLUME:用于数据持久化或共享,就像舞台下的存储空间,用来存放演出需要的物品。
USER:设置运行容器时的用户名,确保安全,就像指定了演员的身份。
第二类
基于Dockerfile中指令的功能和它们在构建Docker镜像过程中的逻辑顺序
基础镜像信息:
这部分通常只包含一个 FROM 指令,用于指定新镜像的基础镜像。这是构建过程的起点。这就像选择一张白纸或特定颜色的纸作为绘画的开始。
维护者信息:
LABEL 指令来指定维护者的联系信息。这有助于识别镜像的来源和负责人。这相当于在画作的边缘写下你的名字和联系方式,让看到这幅画的人都知道是谁创作的。
镜像操作指令:
这部分包括了多个指令,如 ADD、COPY、RUN、ENV、WORKDIR、VOLUME、EXPOSE 等,用于执行构建镜像过程中的各种操作,例如复制文件、执行命令、设置环境变量、设置工作目录、创建卷、暴露端口等。这包括了在纸上绘制、上色、添加纹理等所有艺术创作过程。
容器启动时指令:
这部分主要包含 CMD 和 ENTRYPOINT 指令,定义了容器启动时的行为。CMD 提供了容器启动时默认执行的命令和参数,而 ENTRYPOINT 设置了容器启动时要运行的可执行文件。这告诉你完成画作后,如何展示它(EXPOSE),以及当有人来看这幅画时,应该首先看到什么或从哪个角度欣赏(CMD 和 ENTRYPOINT)。
指令说明
配置指令
配置镜像信息
1. FROM
作用
FROM 指定了新镜像基于哪个已有镜像进行构建。
格式语法
FROM <image>[:<tag>] [AS <name>]
- 是指定的基础镜像的名称或ID。
- 是可选的,用于指定要使用的镜像标签,如果不指定,默认标签是 latest。
- AS 是可选的,用于给基础镜像指定一个别名,用于在 Dockerfile 中引用。
用法
- FROM 指令是 Dockerfile 中的第一个指令,定义了构建过程的起始点。
- 可以指定一个本地镜像或远程仓库中的镜像。
- 可以为镜像指定一个别名,以便在 Dockerfile 中的后续指令中引用。
用法注意事项
- Dockerfile 中必须有且仅有一个 FROM 指令。
- 如果指定的镜像在本地不存在且无法从远程仓库拉取,Docker 构建会失败。
- 使用官方镜像作为基础镜像可以提高构建的安全性和稳定性。
- 避免使用过时的基础镜像,以确保安全性和兼容性。
- 使用 AS 指定别名时,该别名仅在当前 Dockerfile 中有效。
实例
- 使用最新的官方 Ubuntu 镜像作为基础镜像
FROM ubuntu:latest
# 使用 ubuntu 的最新版本作为基础镜像
- 使用指定版本的官方 Python 镜像,并指定别名
FROM python:3.8-slim AS python_app
# 使用 python 3.8 slim 版本作为基础镜像,并设置别名为 python_app
- 使用基础镜像进行多阶段构建
# 第一阶段:构建阶段,使用 buildpack 镜像
FROM buildpack-deps:buster AS build
WORKDIR /app
COPY . .
RUN apt-get update && apt-get install -y nodejs
RUN npm install && npm run build
# 第二阶段:运行阶段,使用更小的 alpine 镜像
FROM alpine:latest
WORKDIR /app
COPY --from=build /app/build ./
CMD ["node", "app.js"]
# 使用 alpine 作为最终镜像的基础,并从 build 阶段复制构建产物
在这个多阶段构建的例子中:
第一阶段使用 buildpack-deps:buster 镜像来执行构建任务,安装依赖并运行构建命令。
第二阶段使用 alpine:latest 镜像作为最终的运行时镜像,并从第一阶段复制构建产物。
2. ENV
作用
设置环境变量,为镜像中的进程提供配置信息。
格式语法
ENV <key> <value>
- 是环境变量的名称。
- 是环境变量的值。
或者
设置多个环境变量:
ENV <key1>=<value1> <key2>=<value2> ...
- 和 等是环境变量的键名。
- 和 等是环境变量的值。
用法
- ENV 指令在 Dockerfile 中用来定义环境变量,这些变量可以被后续指令使用
- 可以在 RUN 指令中引用这些环境变量,或者在容器启动时作为配置参数。
用法注意事项
- 环境变量的值在 Dockerfile 中是纯文本形式,需要确保它们是正确转义的,特别是如果有空格或特殊字符。
- 环境变量的设置在 Dockerfile 中是累加的,相同的变量可以被多次设置,后面的值会覆盖前面的值。
- 环境变量在容器运行时可以被用户覆盖。
实际使用例子
- 设置单个环境变量
FROM ubuntu
ENV MY_VARIABLE "Hello, World"
# 设置环境变量 MY_VARIABLE 的值为 "Hello, World"
- 设置多个环境变量
FROM python:3.8-slim
ENV MY_VAR=value1 \
OTHER_VAR=value2
# 设置两个环境变量 MY_VAR 和 OTHER_VAR
- 在运行时使用环境变量
FROM node:14
ENV NODE_ENV development
WORKDIR /app
COPY . .
RUN npm install && npm run build
CMD ["node", "index.js"]
# 使用环境变量 NODE_ENV 来指定 Node.js 的运行环境
在这个例子中,NODE_ENV 环境变量被设置为 development,这可以影响 Node.js 应用的运行模式和行为。
3.LABEL
作用
- 为镜像提供元数据,有助于识别和管理镜像。
- LABEL 指令是 Dockerfile 中添加元数据的标准方式,它使得镜像的使用者和自动化工具能够更容易地获取和使用镜像信息。
格式语法
LABEL <key>=<value>
或者
LABEL <key1>=<value1> <key2>=<value2> ...
- 是标签的名称。
- 是标签的值。
用法
- LABEL 可以在 Dockerfile 中多次使用,以添加多个元数据。 可以使用 LABEL 指令添加结构化的元数据,例如 JSON
对象。
用法注意事项
- 所有 LABEL 都会在镜像的元数据中累积,因此避免重复添加相同的标签。
- 标签的值应该是字符串,如果需要使用特殊字符或空格,应该正确地转义它们。
- 标签可以包含多行文本,使用反斜杠 \ 进行换行。
实际使用例子
- 添加单个标签
FROM ubuntu
LABEL version="18.04"
# 设置镜像的版本标签
- 添加多个标签
FROM python:3.8-slim
LABEL maintainer="example@example.com" \
description="Python 3.8 Slim Docker Image"
# 设置维护者和描述标签
- 添加结构化标签
FROM alpine
LABEL org.label-schema.schema-version="1.0" \
org.label-schema.name="My App" \
org.label-schema.description="My application description" \
org.label-schema.url="https://myapp.example.com" \
org.label-schema.vcs-url="https://github.com/user/myapp" \
org.label-schema.version="1.2.3" \
org.label-schema.docker.cmd="docker run -p 80:80 myapp"
# 使用org.label-schema 提供结构化的标签
在这个例子中,我们使用了 org.label-schema 命名空间来提供一组结构化的标签,这些标签遵循一定的规范,可以被工具和平台识别和使用。
4.WORKDIR
作用
- 在 Dockerfile 中用来设置容器内的当前工作目录,相当于 shell 中的 cd 命令。这个指令对后续的
RUN、CMD、ENTRYPOINT、COPY 和 ADD 指令都有影响,因为它们都会相对于这个工作目录执行。 - 设置容器内的当前工作目录。
- WORKDIR 指令是 Dockerfile 中设置工作目录的标准方式,它使得 Dockerfile
更加清晰、简洁,并且减少了路径错误的可能性。
格式语法
WORKDIR /path/to/workdir
- /path/to/workdir 是容器内部的绝对路径,或者是相对于之前 WORKDIR 指令设置的路径。
用法
- WORKDIR 指令在 Dockerfile 中用来指定命令执行的目录。
- 可以多次使用 WORKDIR 来改变工作目录。
用法注意事项
- 如果指定的路径不存在,Docker 会自动创建所有需要的中间目录。
- 使用 WORKDIR 可以避免在 Dockerfile 中使用相对路径或重复的绝对路径。
- WORKDIR 设置的目录对于容器的文件系统是持久的,即使容器被删除,镜像中的目录结构仍然存在。
实际使用例子
- 设置工作目录并在此目录下执行命令
FROM ubuntu
WORKDIR /app
COPY . /app
RUN make /app
# 将工作目录设置为 /app,并在该目录下复制当前目录内容并执行 make 命令
- 使用 WORKDIR 避免重复路径
FROM node:14
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
# 将工作目录设置为 /usr/src/app,后续操作都在这个目录下进行
在这个例子中,WORKDIR 指令将工作目录设置为 /usr/src/app,然后 COPY 和 RUN 指令都相对于这个目录执行。
5.ENTRYPOINT
作用
- 在 Dockerfile 中用于指定容器启动时要运行的可执行文件或脚本。与 CMD 指令配合使用,可以定义容器的运行行为。
定义容器启动时要执行的命令。 - ENTRYPOINT 指令是 Dockerfile 中定义容器启动命令的标准方式,它提供了一种灵活的方式来指定容器的行为,并且可以通过
CMD 传递参数。 - 可以接收参数,这些参数在容器启动时作为命令行参数传递。
格式语法
ENTRYPOINT ["executable", "param1", "param2", ...]
- 使用数组形式,确保即使包含空格也能正确解析。
- executable 是要执行的命令或脚本的路径。
- executable:容器启动时要运行的命令或脚本。
- param1, param2, …:传递给 executable 的参数列表。
用法
- ENTRYPOINT 可以独立使用,也可以与 CMD 配合使用。
- 如果没有指定 CMD,容器将使用 ENTRYPOINT 指定的命令作为默认执行命令。
- 如果指定了 CMD,CMD 将作为参数传递给 ENTRYPOINT。
用法注意事项
- ENTRYPOINT 在 Dockerfile 中只能出现一次,如果有多个 ENTRYPOINT 指令,只有最后一个会生效。
- 使用数组形式可以避免 shell 命令解析,确保参数正确传递。
- 如果 ENTRYPOINT 指定的文件不存在或不可执行,容器启动将失败。
实际使用例子
- 指定单一命令作为容器的入口点
FROM ubuntu
ENTRYPOINT ["top", "-b"]
# 容器启动时将执行不带交互界面的 top 命令
- 与 CMD 配合使用
FROM python:3.8-slim
WORKDIR /app
COPY . /app
ENTRYPOINT ["python", "app.py"]
# 容器启动时将执行 /app 目录下的 app.py 脚本
CMD ["arg1", "arg2"]
# CMD 提供的参数将传递给 app.py 脚本
在这个例子中,容器启动时将执行 python app.py 命令,并且 CMD 中指定的参数 arg1 和 arg2 将作为参数传递给 app.py。
6.EXPOSE
作用
-
在 Dockerfile中用于声明容器在运行时监听的端口,它不会实际上发布端口或设置防火墙规则,但它提供了一个声明式的端口配置,使得在部署时可以更容易地使用 docker 命令的 -p 参数来映射端口。
-
EXPOSE 指令是 Dockerfile 中用于端口声明的标准方式,它使得容器的端口配置更加清晰和易于理解。
-
声明容器运行时应该监听的端口号。
格式语法
EXPOSE <port> [/protocol]
EXPOSE <port1> <port2> ... [/protocol]
- 是容器内部监听的端口号。
- protocol 是可选的,指定端口使用的协议(TCP 或 UDP),如果不指定,默认为 TCP。
- :要暴露的端口号。
- /protocol:指定端口使用的通信协议。
用法
- EXPOSE 指令可以在 Dockerfile 中多次使用,以声明多个端口。
- 它主要用于作为文档说明,以及在部署容器时提供端口映射的提示。
用法注意事项
- EXPOSE 不会实际上发布端口,容器端口的发布需要在运行容器时使用 docker run -p 命令实现。
- 可以在 docker-compose.yml 文件中使用端口映射,此时 EXPOSE 指令可以作为参考。
- 即使没有 EXPOSE 指令,容器端口也可以在运行时被映射。
实际使用例子
- 声明单个端口
FROM nginx
EXPOSE 80
# 声明容器应该在 80 端口监听 HTTP 请求
- 声明多个端口
FROM tomcat
EXPOSE 8080 8009
# 声明容器应该在 8080 端口监听 HTTP 请求,在 8009 端口监听 AJP 请求
- 声明端口和协议
FROM mongo
EXPOSE 27017/tcp 27017/udp
# 声明容器在 27017 端口同时监听 TCP 和 UDP 请求
在这个例子中,EXPOSE 指令用于告诉用户和部署系统,这些端口在容器内部被应用程序使用,需要在运行容器时进行适当的端口映射。
7.VOLUME
作用
- Dockerfile 中用于声明容器内的挂载点,这些挂载点可以在容器运行时通过 Docker 客户端的 -v 或 --mount参数绑定到宿主机或其他卷上,实现数据的持久化或共享。
- VOLUME 指令是 Dockerfile 中声明容器内部卷的标准方式,它使得容器中的数据管理更加灵活和强大。
- 声明容器内部的挂载点,用于数据持久化或卷的共享。
格式语法
VOLUME ["/path1", "/path2", ...]
- 使用数组形式,可以一次声明多个挂载点。
- /path1, /path2, …:容器内部的挂载点路径列表。
用法
- VOLUME 指令在 Dockerfile 中用来声明容器内部的卷。
- 这些卷可以在容器运行时与宿主机或其他容器的卷进行绑定。 用法注意事项
- 声明的卷在容器构建时不会创建,它们仅作为声明存在。
- 容器运行时,需要使用 -v 或 --mount 参数来实际创建并绑定卷。
- 使用 VOLUME 可以提高容器的灵活性,使得数据可以在容器之间共享或持久化存储。
实际使用例子
- 声明单个挂载点
FROM ubuntu
VOLUME /data
# 声明容器内部的 /data 目录作为挂载点
- 声明多个挂载点
FROM postgres
VOLUME /var/lib/postgresql/data
# 声明 PostgreSQL 数据库的数据目录作为挂载点
- 在 Dockerfile 中使用 VOLUME 并运行容器
FROM alpine
VOLUME /app/data
WORKDIR /app
COPY . /app
CMD ["sh", "-c", "mkdir -p /app/data && echo 'data stored in /app/data' > /app/data/message"]
# 声明 /app/data 作为挂载点,并在容器启动时创建并写入数据
在这个例子中,VOLUME 指令用于声明 /app/data 作为容器内部的挂载点。在容器运行时,可以使用 -v 参数将宿主机的目录挂载到 /app/data。
8.USER
作用
- 在 Dockerfile中用于指定运行容器时的用户名或用户ID(UID),以及可选的用户组名或组ID(GID)。这个指令对容器的权限和安全性有重要影响。
- USER 指令是 Dockerfile 中控制用户身份的标准方式,它有助于确保容器内的操作符合预期的权限和安全要求。
- 指定容器内执行命令和拥有文件的用户名或UID。
格式语法
USER <user>[:<group>]
- 是要切换的用户名称或用户ID。
- 是可选的,指定用户所属的用户组名称或用户组ID。
- :指定容器执行操作的用户。
- :指定用户所属的组,如果省略,将使用默认的用户组。
用法
- USER 可以在整个 Dockerfile 中多次使用,以切换不同的用户执行命令。
- 它影响 RUN、CMD、ENTRYPOINT 等指令中命令的执行用户。
- 指定的用户必须是基础镜像中已经存在的用户。
用法注意事项
- 如果指定了一个不存在的用户,Docker 将自动创建一个新用户。
- 使用 USER 切换用户可能会影响容器内部的权限设置,特别是涉及到文件系统权限时。
- 在 Dockerfile 中使用 USER root可以执行需要特权的操作,但出于安全考虑,通常建议在完成安装和配置后切换回非特权用户。
实际使用例子
- 切换到特定的用户执行命令
FROM ubuntu
USER johndoe
RUN echo "Hello, world" > /home/johndoe/message
# 切换到用户 johndoe 并创建一个文件
- 使用用户ID和用户组ID
FROM alpine
USER 1000:1000
RUN mkdir /app && touch /app/welcome.txt
# 切换到 UID 为 1000,GID 为 1000 的用户
- 在多步骤构建中切换用户
FROM golang:1.15 AS builder
USER root
RUN apt-get update && apt-get install -y make
FROM scratch
USER nobody
COPY --from=builder /go /go
# 第一阶段使用 root 用户安装 make,第二阶段切换到 nobody 用户
在这个例子中,我们首先在构建阶段使用 root 用户来安装所需的软件包,然后在第二阶段切换到 nobody 用户。这样做可以减少最终镜像的大小并提高安全性。
9.ARG
作用
- 在 Dockerfile 中用于定义变量,这些变量在构建过程中可以通过 --build-arg 参数传入值,或者在 Dockerfile中使用默认值。
- ARG 指令是 Dockerfile 中定义构建参数的标准方式,它使得 Dockerfile更加灵活和可配置,允许用户在构建镜像时自定义参数值。
- 定义构建时的参数变量,可以在 Dockerfile 中的任何地方使用。
格式语法
ARG <name>[=<default value>]
- 是变量的名称。
- [=] 是可选的,默认值,如果未在构建时提供该参数,则使用默认值。
- :参数的名称,必须以字母开头,可以包含字母、数字或下划线。
- :参数的默认值,如果构建时未指定该参数,则使用此值。
用法
- ARG 定义的变量可以在 Dockerfile 中通过 ${variable} 语法引用。
- 可以在构建时使用 --build-arg = 来覆盖 ARG 指令定义的默认值。
用法注意事项
- ARG 定义的变量仅在构建阶段有效,构建完成后,这些变量在运行时不可用。
- 可以在 Dockerfile 中多次使用 ARG 指令来定义多个变量。
- 如果 ARG 出现在 FROM 指令之前,它将被当作构建参数,而不是环境变量。
实际使用例子
- 定义并使用 ARG 变量
FROM ubuntu
ARG VERSION=latest
RUN echo "Using version: ${VERSION}"
# 使用 VERSION 变量并显示信息
- 使用默认值的 ARG 变量
FROM python:3.8-slim as base
ARG BUILD_DEPS="make gcc"
RUN apt-get update && apt-get install -y ${BUILD_DEPS}
# 使用 ARG 变量并安装依赖
- 在构建时覆盖 ARG 变量的默认值
docker build --build-arg VERSION=1.0.0 -t myimage .
在这个例子中,我们在构建时通过 --build-arg 参数指定了 VERSION 变量的值,覆盖了 Dockerfile 中定义的默认值。
10.ONBUILD
作用
- 在 Dockerfile 中用于添加触发器,这些触发器在当前镜像作为其他 Dockerfile 中 FROM 语句的基础镜像时自动执行。
ONBUILD 指令通常用于定义一种模板,让其他人在基于你的镜像创建新镜像时自动执行一些操作,如复制文件或设置环境变量。 - ONBUILD 指令是 Dockerfile 中用于创建智能镜像模板的标准方式,它使得基于这些镜像的构建过程自动化和标准化。
- 定义在后续镜像构建中自动执行的指令。
格式语法
ONBUILD <其他指令>
- <其他指令> 可以是 Dockerfile 中除了 FROM 和 ONBUILD 之外的任何指令。
- <其他指令>:在子镜像构建时自动执行的 Dockerfile 指令
用法
- ONBUILD 指令在 Dockerfile 中定义,但它的实际效果是在基于当前镜像创建的任何新镜像的构建过程中体现。
- 当使用带有 ONBUILD 指令的镜像作为基础镜像时,这些指令会按照它们在 Dockerfile 中出现的顺序执行。
用法注意事项
- ONBUILD 指令在 Dockerfile 中只能出现在 FROM 指令之后。
- ONBUILD 指令在当前镜像的构建过程中没有效果,只在后续使用该镜像作为基础镜像时触发。
- ONBUILD 可以有多个,它们在子镜像构建时按照在Dockerfile 中出现的顺序执行。
- ONBUILD 指令可以被子镜像中的相同指令覆盖。
实际使用例子
使用 ONBUILD 自动 COPY 文件
FROM ubuntu
ONBUILD COPY . /app
ONBUILD RUN make /app
# 当基于此镜像构建新镜像时,会自动复制当前目录下的文件到 /app 并执行 make
- 使用 ONBUILD 设置环境变量
FROM python:3.8-slim
ONBUILD ENV VERSION=latest
# 基于此镜像的任何新镜像都会设置环境变量 VERSION
- 多级 ONBUILD 指令
FROM golang AS builder
ONBUILD RUN go get -d -v github.com/some/dependency
ONBUILD RUN go build -o /app main.go
# 第一阶段构建时获取依赖,第二阶段构建时编译程序
在这个例子中,任何基于 builder 镜像的后续构建都会首先获取依赖,然后编译程序。
11.STOPSIGNAL
作用
- 在 Dockerfile 中用来设置容器接收到的停止信号。这个信号用于容器的优雅关闭,允许容器内的应用程序正确地进行清理和退出。
- STOPSIGNAL 指令是 Dockerfile 中用于自定义容器停止信号的标准方式,它使得容器的停止行为更加灵活和符合特定应用程序的需求。
- 设置容器停止时发送的信号。
格式语法
STOPSIGNAL signal
- signal 是要发送的信号名称或数字。
- signal:可以是信号的名称(如 SIGTERM)或信号的数字(如 15)。
用法
- STOPSIGNAL 指令在 Dockerfile 中用来指定当容器停止时应该发送的信号。
- 默认情况下,如果未设置 STOPSIGNAL,Docker 会发送 SIGTERM 信号给容器。
用法注意事项
- STOPSIGNAL 指令在 Dockerfile 中只能出现一次。
- 指定的信号必须是系统支持的信号之一。
- 信号名称不区分大小写。
实际使用例子
- 设置停止信号为 SIGTERM
FROM ubuntu
STOPSIGNAL SIGTERM
# 设置容器停止时发送 SIGTERM 信号
- 使用信号的数字设置停止信号
FROM nginx
STOPSIGNAL 9
# 设置容器停止时发送 SIGKILL 信号(信号9)
在这个例子中,我们为基于 nginx 镜像的容器设置了停止信号为 SIGKILL。这意味着当 Docker 发出停止容器的请求时,容器将接收到 SIGKILL 信号。
12.HEALTHCHECK
作用
- 在 Dockerfile
中用于设置容器的健康检查,这是用于确定容器是否仍在运行预期任务的一种方法。通过定期地执行健康检查命令,Docker可以知道容器是否健康,从而在容器不健康时采取行动,比如重启容器。 - HEALTHCHECK 指令是 Dockerfile 中用于容器健康监控的标准方式,它为容器的可靠性和稳定性提供了保障。
- 定义容器的健康检查机制。
格式语法
HEALTHCHECK [OPTIONS] CMD command (默认情况下,没有命令)
HEALTHCHECK NONE
- OPTIONS 包括:
- –interval=DURATION:两次健康检查之间的时间间隔。
–timeout=DURATION:健康检查命令运行超时的时间。
–retries=N:当容器健康检查失败时,允许的最大失败次数。 CMD:指定健康检查使用的命令。 - command:要执行的命令,通常是一个测试命令,用以检查容器内服务的状态。
参数解释
- –interval:健康检查的时间间隔。
- –timeout:健康检查命令的超时时间。
- –retries:在认为容器不健康之前,允许的连续失败次数。
- NONE:如果使用 HEALTHCHECK NONE,则禁用所有健康检查。
用法
- HEALTHCHECK 指令定义了容器启动后用来检查其健康状态的命令。
- 可以使用 CMD 指定执行的命令,Docker 将定期执行这个命令。
- 健康检查命令必须在指定的超时时间内退出,并且返回以下状态码之一:
0:成功 - 容器健康。
1:失败 - 容器不健康。
2:保留 - 容器的健康状态未知。
用法注意事项
- 至少需要指定 --interval、–timeout 和 --retries 中的一个选项。
- 如果未指定 --timeout,Docker 会使用默认值,通常是 30 秒。
- 健康检查命令必须在 Dockerfile 中指定,并且只能在Dockerfile 中指定一次。
实际使用例子
- 基本的健康检查设置
FROM nginx
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
# 每 30 秒检查一次,超时时间为 3 秒,使用 curl 命令检查 Nginx 服务
- 禁用健康检查
FROM ubuntu
HEALTHCHECK NONE
# 禁用健康检查
在这个例子中,我们使用 HEALTHCHECK 指令为基于 nginx 镜像的容器设置了一个健康检查,该检查会定期发送 HTTP 请求到容器的本地服务,并根据响应判断服务是否健康。
13.SHELL
作用
- 在 Dockerfile 中用来指定运行容器内命令时使用的 shell 命令行解释器。默认情况下,Docker 使用 /bin/sh作为解释器,但不同的基础镜像可能使用不同的默认 shell。
- SHELL 指令是 Dockerfile 中自定义命令执行环境的标准方式,它使得 Dockerfile 更加灵活,可以适应不同的shell 环境需求。
- 指定 Dockerfile 中所有命令行指令使用的 shell 解释器。
格式语法
SHELL ["executable", "parameters"]
- executable 是 shell 解释器的可执行文件路径。
- parameters 是传递给解释器的参数,可以有多个。
- executable:shell 解释器的路径,如 /bin/bash 或 /bin/sh。
- parameters:可选,用于定制 shell 的行为,如 -c 表示执行命令字符串。
用法
- SHELL 可以在整个 Dockerfile 中使用一次或多次,但通常建议只使用一次以避免混淆。
- 可以指定不同的 shell 解释器和参数,以适应不同的需求。
用法注意事项
- 使用 SHELL 可以改变 Dockerfile 中所有命令的执行环境。
- 在 Windows 上,Docker 容器可能不支持所有的 Unix 命令行解释器。
- 指定的 shell 解释器必须是容器内存在的可执行文件。
实际使用例子
- 更改默认的 shell 解释器为 /bin/bash
FROM ubuntu
SHELL ["/bin/bash", "-c"]
RUN apt-get update && apt-get install -y curl
# 使用 bash 作为默认的 shell 解释器
- 使用 PowerShell 作为 Windows 容器的 shell 解释器
FROM mcr.microsoft.com/windows/servercore:ltsc2019
SHELL ["powershell", "-Command"]
RUN New-Item -ItemType Directory -Path C:\example
# 使用 PowerShell 作为 shell 解释器
在这个例子中,我们为基于 ubuntu 镜像的 Dockerfile 更改了默认的 shell 解释器为 /bin/bash,并且使用了 -c 参数来执行命令字符串。对于 Windows 容器,我们使用了 PowerShell 作为 shell 解释器。
操作指令
具体执行操作
RUN
作用
- 在 Dockerfile中是核心指令之一,用于执行命令并将其结果作为新的层保存在镜像中。这个指令在构建镜像时执行,并且每次执行都会创建一个新的镜像层。
- RUN 指令是 Dockerfile 中执行命令的标准方式,它对于构建包含必要软件和配置的镜像至关重要。
- 在当前镜像的基础上执行命令,并创建一个新的层。
格式语法
RUN command
- command 是要在容器内执行的命令。
- command:Shell 命令或者可执行文件。
用法
- RUN 指令在 Dockerfile 中用来执行任何所需的命令。
- 它可以用来安装软件包、清理文件、执行编译等。
用法注意事项
- RUN 指令执行的命令会在新的层中执行,这可能导致镜像大小增加。
- 建议将相关的命令合并为一个 RUN 指令,以减少层数和优化构建缓存。
- 使用 && 连接命令时,它们会在同一层中顺序执行,但要注意不要引入不必要的依赖。
实际使用例子
- 安装软件包
FROM ubuntu
RUN apt-get update && apt-get install -y curl
# 更新软件包列表并安装 curl
- 使用 shell 形式执行命令
FROM alpine
RUN echo "Hello, world" > /hello.txt
# 创建一个包含 "Hello, world" 的文件 /hello.txt
- 使用 exec 形式执行命令
FROM python:3.8-slim
RUN ["python", "-c", "print('Hello, world')"]
# 使用 exec 形式执行 Python 命令
- 清理安装后的缓存
FROM buildpack-deps
RUN apt-get update && \
apt-get install -y wget && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 安装 wget 并清理安装缓存
在这个例子中,我们使用 RUN 指令来更新软件包列表,安装 wget,然后清理缓存以减小镜像大小。
CMD
作用
- 在 Dockerfile 中用于指定容器启动时默认执行的命令。它定义了容器的运行行为,可以被用户在启动容器时通过命令行参数覆盖。
- CMD 指令是 Dockerfile 中定义容器默认行为的标准方式,它使得容器的启动更加灵活和可配置。
- 指定容器的默认执行命令。
格式语法
CMD ["executable", "param1", "param2", ...]
或者使用 shell 形式:
CMD command param1 param2 ...
- 使用数组形式可以避免 shell 解释器的解析,确保参数正确传递。
- 使用 shell 形式时,command 是在 shell 中执行的命令。
- executable:要执行的命令或脚本的路径。
- param1, param2, …:传递给 executable 的参数列表。
用法
- CMD 指令定义了容器启动时执行的命令和参数。
- 如果 Dockerfile 中有多个 CMD 指令,只有最后一个会生效。
- 用户可以在 docker run 时通过命令行参数覆盖 CMD 指令。
用法注意事项
- CMD 应该返回非零退出码时,容器会立即停止。
- 使用数组形式可以确保即使参数中有空格或特殊字符也能正确执行。
- CMD 可以与 ENTRYPOINT 一起工作,CMD 提供的参数会成为 ENTRYPOINT 的默认参数。
实际使用例子
- 使用 CMD 指定默认命令
FROM ubuntu
CMD ["echo", "Hello, world"]
# 容器启动时将打印 "Hello, world"
- 使用 shell 形式的 CMD
FROM alpine
CMD echo "This is the container's default command"
# 容器启动时将执行 shell 命令并打印信息
- 结合 ENTRYPOINT 使用 CMD
FROM python:3.8-slim
ENTRYPOINT ["python"]
CMD ["myscript.py"]
# 容器启动时将执行 python myscript.py
在这个例子中,CMD 作为 ENTRYPOINT 的参数,指定了默认执行的 Python 脚本。
ADD
作用
- 在 Dockerfile中用于将文件、目录、远程文件URL以及tar压缩文件从构建上下文(通常是Dockerfile所在的目录)复制到容器的文件系统中。
- ADD 指令是 Dockerfile中用于文件复制和内容下载的标准方式,它为构建过程中的文件操作提供了便利。然而,应当谨慎使用,以避免不必要的权限问题和镜像大小增加。
- 从构建上下文复制新文件或目录到容器内部。
- 从URL下载文件并复制到容器内部。
- 解压tar压缩文件到容器内部。
格式语法
ADD <src> <dest>
- 是源文件或目录的路径,或者是URL。
- 是容器内部的目标路径,必须是一个绝对路径,或者是相对于 WORKDIR 指定的路径。
参数解释
- :可以是文件、目录、URL或tar压缩文件。
- :容器内部的路径,新文件或目录将被复制到这里。
用法
- ADD 指令用于将内容复制到容器中。
- 如果 是一个本地tar压缩文件,它将被自动解压到 。
- 如果 不存在,Docker 将根据需要创建所有中间目录。 用法注意事项
- 使用 ADD 时要注意权限问题,复制的文件和目录将拥有容器内root用户的权限。
- ADD 指令不会覆盖容器内部已存在的文件或目录,除非它们是目录类型并且 也是一个目录,这种情况下会进行合并。
- ADD 指令不能复制目录到URL,或URL到目录。
实际使用例子
- 将本地文件复制到容器内
FROM ubuntu
ADD hello.txt /app/
# 将当前上下文中的 hello.txt 文件复制到容器的 /app/ 目录下
- 将本地目录复制到容器内
FROM nginx
ADD . /app
# 将当前上下文的所有内容复制到容器的 /app/ 目录下
- 从URL下载文件并复制到容器内
FROM alpine
ADD http://example.com/remotefile.tar.gz /tmp/
# 从URL下载文件并保存到容器的 /tmp/ 目录下
- 将tar压缩文件自动解压到容器内
FROM busybox
ADD archive.tar.gz /app/
# 将当前上下文中的 archive.tar.gz 解压到容器的 /app/ 目录下
COPY
作用
- COPY 指令是 Dockerfile中用于文件复制的标准方式,它使得将本地文件和目录包含到镜像中变得简单直接。使用时应注意路径和权限设置,以确保构建过程的正确性和安全性。
- 在 Dockerfile 中用于从构建上下文(通常是 Dockerfile 所在的目录)复制新文件或目录到容器的文件系统中。
- 将本地文件或目录复制到容器内部。
格式语法
COPY [--chown=<user>:<group>] <src>... <dest>
- –chown:可选参数,用于设置复制文件的所有者和组。格式为 :。
- :一个或多个源文件或目录的路径,可以是通配符。
- :容器内部的目标路径,必须是一个绝对路径,或者是相对于 WORKDIR 指定的路径。
- :源文件或目录的路径,可以是单个文件、多个文件或目录。
- :容器内部的目标路径。
用法
- COPY 指令用于将文件和目录从构建上下文复制到容器中。 如果 是一个目录, 中的内容将被复制到该目录下。
- 如果 不存在,Docker 将根据需要创建所有中间目录。 用法注意事项
- COPY 只能访问 Dockerfile 所在目录(构建上下文)中的文件和目录,不能访问 Docker 客户端所在机器的其他路径。
- 使用 --chown 可以改变复制文件的所有者和组,适用于需要特定权限的场景。
- COPY 指令不会覆盖容器内已存在的文件,除非使用通配符模式。
实际使用例子
- 将单个文件复制到容器内
FROM ubuntu
COPY hello.txt /app/
# 将当前上下文中的 hello.txt 文件复制到容器的 /app/ 目录下
- 将多个文件复制到容器内
FROM alpine
COPY *.txt /app/
# 将当前上下文中所有扩展名为 .txt 的文件复制到容器的 /app/ 目录下
- 将目录复制到容器内
FROM nginx
COPY . /app
# 将当前上下文的所有内容复制到容器的 /app/ 目录下
- 使用 --chown 更改文件所有者和组
FROM python:3.8-slim
COPY --chown=user:group app /app
# 将当前上下文中的 app 目录复制到容器的 /app/ 目录下,并设置所有者和组