fix(content): harden Docker practice guide

This commit is contained in:
yeasy
2026-06-16 21:23:21 -07:00
parent f4e684afeb
commit 9fdffa9d91
67 changed files with 343 additions and 278 deletions
+29 -28
View File
@@ -4,12 +4,12 @@
在开始前让我们直言不讳**在大多数情况下你应该使用 COPY而不是 ADD**
`ADD` `COPY` 基础上增加了两个额外功能但这些功能往往引入复杂性而非便利
`ADD` `COPY` 基础上增加了两个额外功能它不是 `COPY` 的通用替代品但在少数场景中更合适
1. 自动解压 tar 压缩包有时你想复制一个 .tar.gz 本身 ADD 会意外地解压它
2. 支持从 URL 下载文件这个功能由于网络不稳定已被广泛认为是反模式
2. 支持从 URL 下载公开远程文件并可配合 `--checksum` 做校验
**实践中的建议**除非你明确需要自动解压功能比如官方基础镜像构建根文件系统否则始终使 COPY原因很简单显式优于隐式你的 Dockerfile 6 个月后被接手维护时清晰的意图会让团队少走很多弯路
**实践中的建议**本地普通文件默认 COPY本地 tar 自动解压或公开远程 artifact 下载并校验时用 ADD需要认证请求头重试或自定义解压流程时用 `RUN curl/wget`
### 7.3.1 基本语法
@@ -20,7 +20,7 @@ ADD [选项] ["<源路径>", ... "<目标路径>"]
`ADD` `COPY` 基础上增加了两个功能
1. 自动解压 tar 压缩包
2. 支持从 URL 下载文件 (不推荐)
2. 支持从 URL 下载文件
---
@@ -30,11 +30,11 @@ ADD [选项] ["<源路径>", ... "<目标路径>"]
|------|------|-----|
| 复制本地文件 | | |
| 自动解压 tar | | |
| 支持 URL | | (不推荐)|
| 支持 URL | | (公开 artifact 可配合校验使用)|
| 行为可预测性 | | |
| 推荐程度 | **优先使用** | 解压场景 |
| 推荐程度 | **普通复制优先使用** | 解压本地 Git/公开远程 artifact |
> **笔者建议**除非需要自动解压 tar 文件否则始终使用 COPY明确的行为比隐式的魔法更好
> **笔者建议**普通复制始终优先 COPY只有当你明确需要 ADD 的额外语义时再使用 ADD并把意图写清楚
---
@@ -79,7 +79,7 @@ app.tar.gz 包含: /app/ 目录结果:
```
---
### 7.3.4 URL 下载功能不推荐
### 7.3.4 URL 下载功能谨慎使用
#### 基本用法
@@ -89,32 +89,29 @@ app.tar.gz 包含: /app/ 目录结果:
ADD https://example.com/app.zip /app/app.zip
```
#### 为什么不推荐
#### 使用边界
| 问题 | 说明 |
| 场景 | 建议 |
|------|------|
| 权限固定 | 下载的文件权限为 600通常需要额外 RUN 修改 |
| 不会解压 | URL 下载的压缩包不会自动解压 |
| 缓存问题 | URL 内容变化时不会重新下载 |
| 层数增加 | 需要额外 RUN 清理 |
| 公开版本固定的远程 artifact | 使用 `ADD --checksum=sha256:... URL dest` |
| 需要认证请求头或复杂重试 | 使用 `RUN curl/wget` |
| 下载后需要复杂解压校验或清理 | 使用 `RUN curl/wget`把流程显式写出 |
| URL 内容可变但无校验 | 不建议直接写入 Dockerfile |
#### 推荐替代方案
#### 推荐写法
```docker
## ❌ 不推荐:使用 ADD 下载
## ✅ 公开 artifact:使用 ADD 并固定校验值
ADD https://example.com/app.tar.gz /tmp/
ADD --checksum=sha256:<digest> https://example.com/app.tar.gz /tmp/app.tar.gz
RUN tar -xzf /tmp/app.tar.gz -C /app && rm /tmp/app.tar.gz
## ✅ 推荐:使用 RUN + curl
## ✅ 需要认证、请求头或特殊处理:使用 RUN + curl
RUN curl -fsSL https://example.com/app.tar.gz | tar -xz -C /app
```
优势
`ADD --checksum` 的优势是缓存更精确并且校验值直接绑定到 Dockerfile`RUN curl/wget` 的优势是控制力更强适合企业内网认证下载或复杂处理
- 一条 RUN 完成下载解压清理
- 减少镜像层数
- 更清晰的构建意图
---
@@ -139,6 +136,10 @@ ADD rootfs.tar.gz /
## 解压应用包
ADD dist.tar.gz /app/
## 下载公开 artifact 并校验
ADD --checksum=sha256:<digest> https://example.com/app.tar.gz /tmp/app.tar.gz
```
#### 不适合使用 ADD
@@ -149,9 +150,9 @@ ADD dist.tar.gz /app/
ADD package.json /app/ # ❌
COPY package.json /app/ # ✅
## 下载文件(用 RUN + curl
## 需要认证或复杂下载逻辑(用 RUN + curl/wget
ADD https://example.com/file / # ❌
ADD https://example.com/file / # ❌ 无法传认证信息,也没有显式处理
RUN curl -fsSL ... -o /file # ✅
## 需要保留 tar 不解压(用 COPY)
@@ -203,14 +204,14 @@ COPY . /app/
ADD app.tar.gz /app/
```
#### 3. 不要 ADD 下载文件
#### 3. 远程 artifact 使 ADD 时必须固定校验值
```docker
## ❌ 避免
## ✅ 公开 artifact
ADD https://example.com/file.tar.gz /tmp/
ADD --checksum=sha256:<digest> https://example.com/file.tar.gz /tmp/file.tar.gz
## ✅ 推荐
## ✅ 认证下载或复杂处理
RUN curl -fsSL https://example.com/file.tar.gz | tar -xz -C /app
```