Dockerfile

目录

文档地址

官方文档地址

格式

However, convention is for them to be UPPERCASE to distinguish them from arguments more easily.

虽然dockerfile文件不区分大小写(not case-senstive),但是为了方便我们阅读和区分,通常对关键字使用大写

COMMAND argv

FROM

一个dockerfile文件通常以FROM为开头(但是也可能出现在解析器指令/注释/全局参数ARG之后),FROM用于指定你即将构筑的镜像,是依赖于哪个镜像进行构筑

解析器指令

解析器的指令是可选的,它会影响处理Dockerfile中后续行的行为,以下是它的格式

 # directive=value

指令不区分大小写,但按照使用惯例常使用小写;指令的指区分大小写,指令中不支持行延续字符(Line cotinuation characters),错误案例如下

# dire  \

一种指令只允许出现一次,且指令必须写在FROM之前(构建指令之前),否则视作注释

FROM XXX
# dire  

也不能出现在非解析器指令的注释之后,否则也被视为注释(未知指令也被视为注释)
解析器指令支持以下三种:

  • syntax:声明构建时使用的dockerfile语法版本,推荐使用以下写法来使用最新稳定的版本
# syntax=docker/dockerfile:1
  • escape:用于设置文件中转义字符所使用的字符,默认为\
  • check:用于配置构建检查的评估方式

ENV

在 Dockerfile 中,ENV 指令用于设置环境变量,这些变量会在镜像构建阶段(RUN/COPY 等指令)和容器运行阶段生效,是配置镜像 / 容器的核心方式之一。容器启动后,变量会作为环境变量存在于容器内(可通过 docker exec <容器ID> env 查看)

# 格式1:键值对(空格分隔,推荐)
ENV <key> <value>

# 格式2:等号分隔(值含空格时更清晰)
ENV <key>=<value>

环境变量替换使用以下两种方式

$argv
${argv}
FROM busybox
ENV FOO=/bar
WORKDIR ${FOO}   # WORKDIR /bar
ADD . $FOO       # ADD . /bar
COPY \$FOO /quux # COPY $FOO /quux

ARG

与ENV不同的是仅构建阶段生效,运行阶段消失

RUN

命令执行阶段:容器的构建阶段,目的是修改镜像内容(如安装包,创建目录,编译代码等),执行结果会被提交为新的层。
橘上所述,一个RUN指令会构建一层独立的镜像层,层会被缓存(镜像层过多会增加镜像体积,可通过 docker build --no-cache来清除run指令缓存),因此推荐将多个RUN命令通过&&进行合并

RUN apt update && apt install git -y

RUN <<EOF
apt-get update
apt-get install -y curl
EOF

CMD

执行阶段:容器的启动阶段,在docker run 启动时执行的默认命令,目的是定义容器的默认行为,如果启动时手动指定看命令(如docker run xxx ls -l),则cmd会被覆盖
基本语法与run一致

ENTRYPOINT

常与CMD配合,定义容器的核心启动命令,cmd常作为其的默认参数
目的是让容器以可执行程序的方式运行,比如:

  • 启动nginx服务(固定nginx,参数通过CMD配置)

即ENTRYPOINT固定主命令,CMD定义默认参数--容器启动时的最终命令:ENTRYPOINT+CMD

ENTRYPOINT ["nginx","-g"] #EXEC格式
CMD ["daemon off;"]

最终命令

nginx -g daemon off;

若docker run xx debug传参就变成

nginx -g debug

因为CMD可被覆盖
需要注意的是若ENTRYPOINT是SHELL格式来书写,那么CMD和docker run传参都会无效(shell 格式独占执行),shell格式会隐式启动sh而非主业务程序,一个Dockerfile仅最后一个ENTRYPOINT生效

LABLE

采用键值对的形式添加元数据

LABEL \
    author="张三 <zhangsan@example.com>" \
    version="1.0.0" \
    description="基于Ubuntu的Python应用镜像" \
    license="MIT"

MAINTAINER 是 Docker 旧指令(已被废弃),推荐用 LABEL maintainer="xxx" 替代

EXPOSE

声明容器对外暴露接口,只是一个声明,而非实际的端口映射,不会自动将端口映射到宿主机,需要通过docker run -p来指定

# 声明80端口(TCP)、53端口(UDP)
EXPOSE 80 53/udp

通过docker inspect来查看镜像想要暴露的端口

COPY

在 Dockerfile 中,COPY 指令是纯文件 / 目录复制工具,核心作用是将构建上下文(本地)的文件 / 目录复制到镜像的指定路径,语义清晰、行为可控,是 Docker 官方推荐的默认文件复制方式(仅在需要解压本地 tar 压缩包时才用 ADD)。

# 基础格式:源路径 目标路径
COPY <src>... <dest>

# 多源复制:多个本地文件/目录复制到同一目标目录
COPY <src1> <src2> <src3>... <dest>

# 进阶:指定复制后的文件所有者(Docker 17.09+ 支持)
COPY --chown=<user>:<group> <src> <dest>

使用场景是纯文件/目录复制

ADD

在 Dockerfile 中,ADD 指令用于将本地文件 / 目录、远程 URL 资源(但是下载失败不重试,也无超时控制,建议用 RUN wget -O /tmp/file.tar.gz https://xxx 替代)或压缩包复制到镜像的指定路径,是比 COPY 更强大的文件复制指令(包含 COPY 所有功能,且增加了自动解压、远程下载特性)。

# 复制本地app.py到镜像/app目录
ADD app.py /app/

# 复制本地src目录下所有内容到镜像/app/src目录
ADD src/ /app/src/

# 通配符复制所有txt文件到/app/docs
ADD *.txt /app/docs/

自动解压本地压缩包(远程不会)

# 本地有app.tar.gz,ADD会自动解压到/app目录(无需手动tar -xzf)
ADD app.tar.gz /app/

推荐仅在解压时使用ADD

VOLUME

和EXPOSE一样用于声明,但是若运行容器时未通过 -v/--mount 指定宿主机挂载路径,Docker 会自动创建匿名卷(路径为 /var/lib/docker/volumes/<随机ID>/_data),并挂载到声明的目录。

# 未指定挂载路径,Docker自动创建匿名卷
docker run -d my-mysql-image
# 查看自动创建的卷
docker volume ls

最佳实践:

  • 仅将可变数据目录(日志/数据库/用户上传)做成卷,避免应用代码(代码应打包进镜像)
  • 用命名卷代替匿名卷,即-v指定,生产环境用--mount代替-v
  • 若需要给卷提供初始数据,应先在镜像中写入,再声明成卷
  • 避免在VOLUME后修改目录(声明的目录无法在后续指令中修改)

USER

在 Dockerfile 中,USER 指令用于指定后续构建阶段(RUN/CMD/ENTRYPOINT 等)执行命令的用户 / 用户组,同时也决定了容器运行时的默认执行用户,核心作用是避免容器以 root 用户运行(提升安全性)。

WORKDIR

在 Dockerfile 中,WORKDIR 指令用于设置后续指令的工作目录(相当于 Linux 的 cd 命令,但更安全、可预测,自动创建不存在的目录),后续的 RUN/COPY/ADD/CMD/ENTRYPOINT 等指令都会基于该目录执行,核心作用是统一容器内的操作路径,避免硬编码绝对路径。

SHELL

在 Dockerfile 中,SHELL 指令用于自定义执行 shell 命令时的默认 shell 程序及参数,核心作用是覆盖 Docker 内置的 shell 解释器(默认 /bin/sh -c),适配不同系统(如 Windows)或定制 shell 行为(如开启严格模式)。

ONBUILD

在 Dockerfile 中,ONBUILD 指令是构建触发器:它为当前镜像添加「后续构建的触发指令」—— 当该镜像被作为基础镜像(FROM)构建新镜像时,ONBUILD 中定义的指令会自动执行(相当于 “继承并运行” 触发指令),核心作用是实现镜像的 “模板化”,简化基于该镜像的二次构建流程。

# 格式:ONBUILD + 任意Dockerfile指令(除ONBUILD/FROM/MAINTAINER外)
ONBUILD <Dockerfile指令>

# 示例:触发复制、运行命令
ONBUILD COPY . /app
ONBUILD RUN npm install --production
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容