【Docker基础五】Dockerfile指令

Dockerfile 是一个文本文件,它包含了一系列的指令和参数,用来自动化构建 Docker 镜像的过程。每一个指令通常都会创建镜像的一层。下面是一些常用的 Dockerfile 指令。

1、FROM

语法FROM [:] [AS ]
用法:设定基础镜像,所有后续的指令都基于这个基础镜像来构建。指定一个已存在的镜像作为新镜像的起点。

示例

# 使用官方的 Node.js 镜像作为基础镜像
FROM node:14

# 为多阶段构建指定一个名称
FROM python:3.8 AS builder

多阶段示例:

# 第一阶段,使用 Node.js 镜像构建前端静态文件
FROM node:12 AS build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./ ./
RUN npm run build

# 第二阶段,使用 Nginx 镜像来提供服务
FROM nginx:stable
COPY --from=build-stage /app/build /usr/share/nginx/html

# 在这个多阶段构建的例子中,第一阶段使用了 node:12 镜像,
# 标记为 build-stage,用于构建前端静态文件。第二阶段则使用 nginx:stable 镜像,
# 从第一阶段复制构建好的静态文件到 Nginx 服务的相应目录中。这样做的好处是,
# 最终的镜像不包含构建前端所需的 Node.js 环境,从而降低了镜像的大小。

2、RUN

语法RUN  (shell 格式) 或 RUN ["executable", "param1", "param2"] (exec 格式)
用法:执行命令并创建新的镜像层。用于安装软件包、创建文件夹、下载文件等。

示例

# 使用 shell 形式安装软件包
RUN apt-get update && apt-get install -y git

# 使用 exec 形式执行命令
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "nginx"]

3、CMD

语法CMD ["executable","param1","param2"] (exec 格式) 或 CMD command param1 param2 (shell 格式)
用法:提供容器默认的执行命令。设置容器启动后默认执行的命令和参数。

示例

# 为容器提供默认运行的命令
CMD ["node", "app.js"]

# 使用 shell 形式提供默认命令
CMD echo "Hello, Docker!"

# 当使用 ENTRYPOINT 定义了可执行程序时,CMD 指定所需的参数。
# 在这个例子中,如果你没有给 docker run 提供额外的命令行参数,
# 容器将会输出 "Hello, World!"。如果你提供了额外的参数,
# 比如 docker run  Hello, Docker!,
# 那么容器将会输出 "Hello, Docker!",因为 CMD 中的默认参数被覆盖了。
ENTRYPOINT ["/bin/echo"]
CMD ["Hello, World!"]

注意:CMD 只应该在 Dockerfile 中使用一次。如果定义了多个 CMD 指令,只有最后一个会生效。

4、LABEL

语法LABEL = = ...
用法:添加元数据。为镜像添加元数据,如维护者信息、版本信息等。

示例

# 添加单个标签
LABEL version="1.0"

# 添加多个标签
LABEL maintainer="[email protected]" description="this is a description"

5、EXPOSE

语法EXPOSE [/...]
用法:声明容器运行时监听的端口。用于指定容器在运行时监听的端口号,供外部连接使用。

示例

# 暴露 80 端口
EXPOSE 80

# 暴露 80 端口和 443 端口
EXPOSE 80 443

# 暴露 7000 端口使用 TCP 和 7001 使用 UDP
EXPOSE 7000/tcp 7001/udp

6、ENV

语法ENV = ...
用法:设置环境变量。为镜像构建过程和容器运行时设置环境变量。

示例

# 单个环境变量
ENV MY_NAME="John Doe"

# 多个环境变量
ENV MY_NAME="John Doe" \
    MY_DOG="Rex" \
    MY_CAT="Whiskers"

# 使用环境变量的好处是可以在不更改 Dockerfile 的情况下,
# 通过修改环境变量的值来调整容器的行为,这可以在运行容器时通过
# docker run 命令的 -e 或 --env 选项来实现、
docker run -e "MY_NAME=Jane Doe" -e "MY_CAT=Garfield" myimage

7、ADD

语法ADD <原路径> <目标路径> 

  • 原路径为:可以是构建上下文中的一个文件或目录,也可以是一个 URL。
  • 目标路径为:是容器内部的绝对路径,或相对于工作目录(WORKDIR)的相对路径。

用法:复制新文件、目录或远程文件URL到容器的文件系统中指定路径。用于将宿主机的文件添加到镜像中。

  • 如果 <源路径> 是一个本地压缩格式的归档文件(如 tar、gzip、bzip2 等),ADD 会自动解压缩这些文件到 <目标路径>
  • 如果 <源路径> 是一个 URL,ADD 会自动下载这个 URL 的内容到 <目标路径>
  • ADD 指令会保留源文件或目录的所有权限信息。

示例

# 添加本地的 test.txt 文件到容器的 /tmp 目录
ADD test.txt /tmp/

# 添加一个目录到容器中的 /path/in/container
ADD my_directory /path/in/container

# 从远程 URL 添加文件到容器中的 /path/in/container
ADD https://example.com/big.tar.xz /path/in/container

# 添加本地的压缩文件 archive.tar.gz,并自动解压到 /path/in/container
ADD archive.tar.gz /path/in/container/

注意:虽然ADD 功能强大,但 Docker 官方文档推荐尽可能使用 COPY 指令,因为 COPY 更透明。COPY 只支持基本的复制文件和目录的功能,没有自动解压缩的功能,也不支持从 URL 添加文件。如果不需要 ADD 的特殊功能,使用 COPY 是更好的选择。

8、COPY

语法COPY [--chown=:] ...
用法:复制新文件或目录到容器的文件系统中指定路径。类似 ADD,但是不会自动解压缩文件或者支持 URL。

示例

# 复制当前目录下的 test.txt 到容器的 /tmp 目录
COPY test.txt /tmp/

# 复制当前目录下的文件到容器中的 /tmp,保持原有的文件名
COPY . /tmp/

# 使用多阶段构建时,可能会从一个阶段复制文件到另一个阶段
# 假设在之前的阶段中有一个名为 builder 的阶段
COPY --from=builder /app/output /app/

注意:

  • <源路径> 必须在构建上下文中,不能是构建上下文外部的文件或目录。
  • 如果 <源路径> 是目录,则复制目录内的所有内容(不包括目录本身)。
  • 如果 <目标路径> 不存在,它将被自动创建,包括任何必要的中间目录。

9、ENTRYPOINT

语法ENTRYPOINT ["executable", "param1", "param2"] (exec 格式) 或 ENTRYPOINT command param1 param2 (shell 格式)
用法: 配置容器启动时运行的命令,不会被 docker run 提供的参数覆盖。允许容器像命令一样运行,并且可以向容器传递额外的参数。

示例

# 使用 exec 形式设置入口点
ENTRYPOINT ["node", "app.js"]

# 使用 shell 形式设置入口点
ENTRYPOINT exec java -jar /usr/share/tag/app.jar

# 结合 CMD 使用,CMD 提供了默认参数
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]

10、VOLUME

语法VOLUME ["/data"]
用法:创建一个可以从本地主机或其他容器挂载的挂载点。用于指定挂载点来持久化数据。

示例

# 创建一个挂载点目录
VOLUME /data

# 创建多个挂载点
VOLUME ["/data", "/var/log"]

使用:如果你想要启动一个容器,并将本地目录 /path/on/host 挂载到容器的 /myvol 目录,你可以使用以下命令:

# 以下例子中,/path/on/host 是你主机上的目录,/myvol 是容器内的挂载点。
# 使用这种方式,你可以在容器之间共享和重用数据。
docker run -v /path/on/host:/myvol myimage
# 或者新的 --mount 语法
docker run --mount type=bind,source=/path/on/host,target=/myvol myimage

注:

  • 数据持久化:卷是用来持久化数据的,即使容器被删除,卷中的数据也会保留。

  • 数据共享与重用:卷可以在容器之间共享和重用。例如,数据库的数据可以存储在卷中,供其他容器访问。

  • 容器间解耦:卷可以帮助解耦容器与数据,使得容器的迁移和备份更加容易。

  • 性能:卷通常可以提供比容器层更好的性能,特别是对于有大量写入操作的应用。

  • 管理:卷的生命周期独立于容器,可以使用 Docker 的卷管理命令来管理。

  • 匿名卷与命名卷:在 Dockerfile 中声明的卷是匿名的,但是用户在使用 docker run 命令时可以通过 -v 或 --mount 标志来创建命名卷或绑定挂载

11、USER

语法USER [:]
用法:指定运行容器时的用户名或 UID(和可选的用户组或 GID)。确保容器以特定的用户权限运行。

示例

# 切换到已存在的用户
USER john

# 切换到 UID
USER 1000

12、WORKDIR

语法WORKDIR /path/to/workdir
用法:为 RUN、CMD、ENTRYPOINT、COPY 和 ADD 设置工作目录。

示例

# 设置工作目录
WORKDIR /app

# 在前一个 WORKDIR 的基础上,设置相对路径的工作目录
WORKDIR /app/build

13、ARG

语法ARG [=]
用法: 定义构建时的变量。

示例:

# 定义了一个名为 VERSION 的变量,默认值为 latest
ARG VERSION=latest

# 使用 ARG 定义的变量来指定基础镜像的版本
FROM alpine:$VERSION

# 构建过程使用 alpine:3.12 作为基础镜像。
docker build --build-arg VERSION=3.12

14、ONBUILD

语法ONBUILD
用法: 添加触发器指令,当镜像作为基础镜像时,触发器指令将被执行。

示例:

# 当构建一个继承了此镜像的 Dockerfile 时,运行 npm install
ONBUILD RUN npm install

# 添加触发器拷贝文件
ONBUILD ADD . /app/src

15、STOPSIGNAL

语法STOPSIGNAL signal
用法: 设置停止容器时发送给容器的系统调用信号。

示例:

# 设置 STOPSIGNAL 为 SIGTERM
STOPSIGNAL SIGTERM

16、HEALTHCHECK

语法HEALTHCHECK [OPTIONS] CMD command 或 HEALTHCHECK NONE
用法: 告诉 Docker 如何测试容器以检查它是否仍在运行。

示例:

# 设置健康检查命令
HEALTHCHECK CMD curl --fail http://localhost:8080/ || exit 1

# 设置带有选项的健康检查
HEALTHCHECK --interval=5m --timeout=3s \
  CMD curl -f http://localhost/ || exit 1

# 禁用健康检查
HEALTHCHECK NONE

17、SHELL

语法SHELL ["executable", "parameters"]
用法: 设置运行命令时使用的默认 shell。

示例:

# 更改默认 shell 到 powershell
SHELL ["powershell", "-command"]

你可能感兴趣的:(Docker基础,docker,容器,运维)