Dockerfile指令介绍

docker构建配置文件指令介绍

常用指令介绍
  • FROM指令

FROM指令用于初始化一个新的构建阶段,并为后续指令设置基础镜像。因此,有效的Dockerfile必须从FROM指令开始。该镜像可以是任何有效的镜像(可以是公共镜像仓库库或者自定义镜像仓库)

语法:FROM < image>[:< tag> | @< digest>] 
例如:
FROM mysql
FROM mysql:latest
FROM mysql:5.7
FROM mysql@sha:bf1c2b3e094fa12d9e87a

通常一个镜像都是以一个已存在的镜像(操作系统或其他镜像)为基础,在这个基础镜像之上叠加一到多个新的层,最终生成能满足特定用户需求的镜像。如果在一个Dockerfile中指定多条FROM指令,则一次可以生成多个镜像


  • MAINTAINER– 已弃用
    功能描述:填写镜像维护人名称,邮件地址可选
语法:MAINTAINER < name> < mail_adrr>

建议使用LABEL指令,该指令在后续会介绍


  • RUN
    功能描述:
语法:
RUN <command>(shell格式,命令在shell中运行,
默认情况下/bin/sh -c在Linux或cmd /S /C  Windows 上运行)

RUN ["executable", "param1", "param2"](exec模式)

该RUN指令将在当前镜像之上执行所有命令,并提交结果。生成的提交镜像将用于下一步Dockerfile。

在shell形式中,可以使用(反斜杠)将一条RUN指令继续到下一行。例如,考虑以下两行:

例如:RUN yum install -y unzip openjdk \
          && unzip xx.zip \
          && yum remove unzip

注意:要使用’/bin/sh’以外的其他shell,请使用exec形式传入所需的shell。例如, RUN ["/bin/bash", “-c”, “echo hello”]

注意:与shell模式不同的是,exec模式不会调用命令shell。这意味着不会进行常规的包装处理。例如,RUN [ “echo”, “$PATH” ]将不会对进行变量替换$PATH。如果要进行shell处理,则可以使用shell形式或直接执行shell,例如:RUN [ “sh”, “-c”, “echo $PATH” ]。当使用exec模式并直接执行shell时(例如在shell表单中),是由shell进行环境变量处理,而不是docker。


  • CMD
    功能描述:CMD用于指定容器启动时执行的命令,每个Dockerfile只能有一个CMD命令,多个CMD命令只执行最后一个。若容器启动时指定了运行的命令,则会覆盖掉CMD中指定的命令。
语法:
CMD ["executable","param1","param2"](exec模式,这是首选形式)
CMD ["param1","param2"](作为ENTRYPOINT的默认参数)
CMD command param1 param2(shell模式)

Dockerfile中只能有一条指令CMD指令。如果您列出多条CMD指令 则只有最后一条CMD会生效。
CMD的主要目的是为执行的容器提供默认值。这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定一条ENTRYPOINT指令。
注意:如果CMD用于提供ENTRYPOINT 指令的默认参数,则CMD和ENTRYPOINT指令均应使用JSON数组格式指定。


  • LABEL

LABEL指令将元数据添加到镜像。LABEL是键值对。要在LABEL值中包含空格,需要使用引号和反斜杠。

LABEL <key>=<value> <key>=<value> <key>=<value> ...

一些用法示例:

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."

一个镜像可以有多个标签,也可以在一行上指定多个标签。在Docker 1.10之前的版本中,这减小了最终映像的大小,但是情况不再如此。您仍然可以通过以下两种方式之一选择在一条指令中指定多个标签:

LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"

你的镜像将继承基础或父镜像(FROM指令中的镜像)中包含的LABEL。如果标签已经存在但具有不同的值,则最上层的值将覆盖任何先前设置的值。

要查看图像的标签,请使用docker inspect命令。


  • EXPOSE
EXPOSE <port> [<port>/<protocol>...]

EXPOSE指令通知Docker容器在运行时监听指定的网络端口。您可以指定端口是侦听TCP还是UDP,如果未指定协议,则默认值为TCP。
EXPOSE指令实际上并未发布端口。它充当构建镜像的人与运行容器的人之间的一种文档约定,说明对外暴露哪些端口的信息。要在运行容器时实际发布端口,请使用-p标记docker run对外暴露和映射一个或多个端口,或者使用-P标记发布所有公开的端口并将它们映射到高阶端口,默认情况下,EXPOSE假定为TCP。您还可以指定UDP,例如:
EXPOSE 80/udp


  • ENV
ENV <key> <value>
ENV <key>=<value> ...
例如:
ENV MYSQL_USER=root
ENV MYSQL_USER root

ENV指令将环境变量key设置为value。此值将在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换。

该ENV指令有两种形式。第一种形式,ENV 将一个环境变量设置为一个值。第一个空格之后的整个字符串将被视为value-包括空格字符。该值将为其他环境变量解释,因此如果不对引号字符进行转义,则将其删除。

第二种形式ENV key=value …允许一次设置多个变量。请注意,第二种形式在语法中使用等号(=),而第一种形式则不使用等号(=)。像命令行解析一样,引号和反斜杠可用于在值中包含空格。
例如:

ENV env1="env 1" env2=env\ 2\ key
    env3=env3

等价于

ENV env1 env 1
ENV env2 env 2 key
ENV env3 env3

ENV从构建后的镜像运行容器时,使用设置的环境变量将保留。可以使用docker inspect查看环境变量,使用docker run --env key=value来改变这些预设好的环境变量对应的值


  • ADD
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] 
(此格式对于包含空格的路径是必需的)

注意:此–chown功能仅支持在Linux平台上构建镜像的Dockerfile上,而在Windows平台上不起作用。由于用户和组所有权概念不会在Linux和Windows之间转换,因此使用/etc/passwd和/etc/group将用户名和组名转换为ID的使用限制了此功能仅对基于Linux OS的容器可用。

ADD指令用于复制文件到镜像上,支持本地目录或远程文件URL ,并将它们添加到镜像的文件系统的dest中。

ADD test* /usr/images/        # 添加所有以test为文件头的文件到/usr/images/下

src可以指定多个资源,但是如果它们是文件或目录,则将其路径解释为相对于构建上下文源的路径。
dest是一个绝对路径,或目标镜像中WORKDIR的相对路径。

ADD a.file tmp/   # 添加a.file 到`WORKDIR`/tmp/下
ADD b.flie /tmp/  # 添加 /absolutb.file到/tmp/目录下

  • COPY
语法:COPY org dest
复制本地主机org目录或文件到镜像中的desc,desc不存在时会自动创建。

  • ENTRYPOINT
语法:
ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1,param2 会在shell中执行。
用于配置容器启动后执行的命令,这些命令不能被docker run提供的参数覆盖。和CMD一样,每个Dockerfile中只能有一个ENTRYPOINT,当有多个时最后一个生效。

  • VOLUME
语法: VOLUME ["/data"]
作用是创建在本地主机或其他容器可以挂载的数据卷,用来存放数据。

  • USER
格式为:USER username
指定容器运行时的用户名,后续的RUN也会使用指定的用户。

除了使用已有的系统用户(通常是root、deamon等)之外,我们更多的是使用自己创建的用户,因为这样更安全。在USER命令之前可以使用RUN命令创建需要的用户。
例如:RUN groupadd -r mysql && useradd -r -g mysql mysql


  • WORKDIR
语法: WORKDIR path

为容器运行指定工作目录,可以使用多个WORKDIR指令,若后续指令用得是相对路径,则会基于之前的命令指定路径。

<think>嗯,用户想了解Dockerfile指令的详解和用法示例。首先,我需要回忆一下常见的Dockerfile指令有哪些。比如FROM、RUN、COPY、ADD、CMD这些基础指令,还有像WORKDIR、ENV、EXPOSE、VOLUME、ARG、LABEL这些进阶指令每个指令的作用和区别是什么,得一一理清楚。 然后,用户可能对每个指令的具体用法和示例感兴趣。比如,FROM用来指定基础镜像,RUN用来执行命令,COPY和ADD的区别是什么?记得ADD可以自动解压和从URL下载,但一般推荐用COPY,除非需要那些额外功能。CMD和ENTRYPOINT的区别也是一个重点,CMD设置默认命令,可以被覆盖,而ENTRYPOINT是入口点,通常结合使用。 接下来,用户可能需要实际的例子来理解这些指令。比如WORKDIR设置工作目录,可以避免多次使用cd命令。ENV设置环境变量,方便后续指令引用。EXPOSE声明端口,但实际映射需要在运行指定。VOLUME创建挂载点,ARG构建的变量,LABEL添加元数据。 还要注意用户提供的引用内容,里面有提到构建命令docker build -t [images]:[tag] [dockerfile path],以及工作目录的设置。需要确保在回答中提到这些引用中的例子,并正确标注引用标记。比如WORKDIR的例子来自引用3,构建命令来自引用1。 用户可能还想知道最佳实践,比如为什么推荐使用COPY而不是ADD,如何分层优化镜像大小,多阶段构建的好处。这些内容能帮助用户写出更高效的Dockerfile。同,常见问题部分可以解答他们在使用中可能遇到的困惑,比如指令执行顺序,CMD和ENTRYPOINT的优先级。 最后,生成相关问题要围绕用户可能深入询问的点,比如指令执行顺序、多阶段构建、优化方法、环境变量设置等。确保问题有针对性,能引导用户进一步学习。</think>### Dockerfile指令详解及用法示例 --- #### 一、基础指令 1. **FROM** 指定基础镜像,所有Dockerfile必须以`FROM`开头。 ```dockerfile FROM ubuntu:20.04 # 使用Ubuntu 20.04作为基础镜像 ``` 2. **RUN** 执行命令并创建新的镜像层,常用于安装软件包。 ```dockerfile RUN apt-get update && apt-get install -y nginx # 更新并安装nginx[^2] ``` 3. **COPY** 将本地文件复制到镜像中,需明确指定路径。 ```dockerfile COPY ./app /usr/src/app # 复制本地app目录到镜像的/usr/src/app ``` 4. **ADD** 类似`COPY`,但支持自动解压压缩文件或从URL下载资源。 ```dockerfile ADD https://example.com/file.tar.gz /opt # 下载并解压文件到/opt ``` 5. **CMD** 设置容器启动的默认命令(可被`docker run`覆盖)。 ```dockerfile CMD ["nginx", "-g", "daemon off;"] # 启动nginx服务 ``` --- #### 二、进阶指令 1. **WORKDIR** 设置后续命令的工作目录,类似`cd`命令。 ```dockerfile WORKDIR /app # 后续命令在/app目录下执行[^3] ``` 2. **ENV** 设置环境变量,可被后续指令或容器运行使用。 ```dockerfile ENV NODE_ENV=production # 定义环境变量 ``` 3. **EXPOSE** 声明容器运行监听的端口(需通过`-p`映射实际端口)。 ```dockerfile EXPOSE 80 # 声明容器使用80端口 ``` 4. **VOLUME** 创建匿名数据卷,用于持久化数据。 ```dockerfile VOLUME /var/log # 挂载日志目录 ``` 5. **ARG** 定义构建的变量(仅在构建阶段有效)。 ```dockerfile ARG APP_VERSION=1.0 COPY app-$APP_VERSION.tar.gz /app ``` 6. **LABEL** 为镜像添加元数据(如维护者信息)。 ```dockerfile LABEL maintainer="dev@example.com" ``` --- #### 三、最佳实践 1. **分层优化** - 合并多个`RUN`指令减少镜像层数 ```dockerfile RUN apt-get update && \ apt-get install -y git curl ``` 2. **多阶段构建** ```dockerfile # 构建阶段 FROM golang:1.18 AS builder COPY . . RUN go build -o /app # 最终阶段 FROM alpine:latest COPY --from=builder /app /app CMD ["/app"] ``` 3. **清理缓存** ```dockerfile RUN apt-get update && apt-get install -y \ package1 \ package2 \ && rm -rf /var/lib/apt/lists/* ``` --- #### 四、构建镜像示例 ```bash # 根据Dockerfile构建镜像 docker build -t myapp:v1 . # 使用当前目录的Dockerfile[^1] ``` --- #### 五、常见问题 1. **COPY与ADD的区别** - `ADD`支持自动解压和URL下载,但推荐优先使用`COPY`保持行为明确。 2. **CMD与ENTRYPOINT的关系** - `ENTRYPOINT`定义容器入口,`CMD`提供默认参数,组合使用可实现灵活的命令覆盖。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

banche168

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值