Complete Dockerfile instruction reference list

This commit is contained in:
yeasy
2026-04-27 23:17:39 +00:00
parent 3d3befa16a
commit 16203c5018
16 changed files with 86 additions and 102 deletions
+4 -4
View File
@@ -86,7 +86,7 @@ RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
$ docker build -t nginx:v3 .
```
在当前版本的 Docker `docker build` 默认会通过 Buildx 调用 BuildKit但如果你显式设置了 `DOCKER_BUILDKIT=0`或正在使用 Windows container mode行为会回到 legacy builder因此你更常看到的是 `[+] Building ...` 这类输出为了帮助理解每一步如何形成镜像历史下面仍展示一种较容易阅读的 legacy builder 经典输出形式
在当前版本的 Docker `docker build` 默认会通过 Buildx 调用 BuildKit因此你更常看到的是 `[+] Building ...` 这类输出为了帮助理解每一步如何形成镜像历史下面仍展示一种较容易阅读的经典输出形式
```bash
Sending build context to Docker daemon 2.048 kB
@@ -98,7 +98,7 @@ Step 2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
Removing intermediate container 9cdc27646c7b
Successfully built 44aa4490ce2c
```
这段输出清晰展示了 legacy builder 的构建过程 `Step 2` `RUN` 指令对应一次临时构建容器执行命令生成新的镜像层再删除中间容器默认的 BuildKit 后端通常不会把这些中间容器和中间镜像以这种形式暴露给用户每条会改文件系统的指令都会生成新的层这一点并没有改变
从命令的输出结果中我们可以清晰的看到镜像的构建过程 `Step 2` 如同我们之前所说的那样`RUN` 指令启动了一个容器 `9cdc27646c7b`执行了所要求的命令并最后提交了这一层 `44aa4490ce2c`随后删除了所用到的这个容器 `9cdc27646c7b`
这里我们使用了 `docker build` 命令进行镜像构建其格式为
@@ -111,7 +111,7 @@ docker build [选项] <上下文路径/URL/->
如果注意会看到 `docker build` 命令最后有一个 `.``.` 表示当前目录 `Dockerfile` 就在当前目录因此不少初学者以为这个路径是在指定 `Dockerfile` 所在路径这么理解其实是不准确的如果对应上面的命令格式你可能会发现这是在指定 **上下文路径**那么什么是上下文呢
首先要理解 `docker build` 的工作原理今天的 `docker build` 通常会通过 Buildx BuildKit 后端发起构建请求无论后端运行在本机还是远端位置参数指定的都是 **构建上下文**也就是构建器可以访问到的文件集合
首先要理解 `docker build` 的工作原理今天的 `docker build` 默认会通过 Buildx BuildKit 后端发起构建请求无论后端运行在本机还是远端位置参数指定的都是 **构建上下文**也就是构建器可以访问到的文件集合
当我们进行镜像构建的时候并非所有定制都会通过 `RUN` 指令完成经常还需要把本地文件复制进镜像比如通过 `COPY` 指令`ADD` 指令等因此构建器必须能够访问这些文件而它能访问的范围正是你传给 `docker build` 的那个上下文
@@ -124,7 +124,7 @@ COPY ./package.json /app/
```
这并不是要复制执行 `docker build` 命令所在的目录下的 `package.json`也不是复制 `Dockerfile` 所在目录下的 `package.json`而是复制 **上下文 (context)** 目录下的 `package.json`
因此`COPY` 这类指令中的源文件路径都应该以构建上下文为基准来理解 `COPY ../package.json /app` 这样的写法前导的越界 `../` 会被规范化掉最终仍只能在上下文根内解析换句话说构建器并不能借此读取上下文之外的宿主机文件如果真的需要那些文件应该先把它们放进上下文目录或重新选择合适的上下文
因此`COPY` 这类指令中的源文件路径都应该以构建上下文为基准来理解对于 legacy builder `COPY ../package.json /app` 这样的写法会直接报错而在 BuildKit 前导的越界 `../` 会被剥离并重新解释为上下文内路径无论是哪种情况构建器都无法读取上下文之外的宿主机文件如果真的需要那些文件应该先把它们放进上下文目录或重新选择合适的上下文
现在就可以理解刚才的命令 `docker build -t nginx:v3 .` 中的这个 `.`实际上是在指定上下文目录而不是单纯指定 `Dockerfile` 所在目录