Dockerfile构建中ADD/COPY指令
COPY 和 ADD 指令如果目标路径不存在,会自动创建目标目录(包括多级目录)。
ADD/COPY
Docker 在执行:
1 | COPY src /app/ |
或
1 | ADD src /app/ |
逻辑是:
- 如果
/app/不存在,Docker 会自动创建它;
- 如果
- 如果
/app/存在且是目录,则文件复制进该目录;
- 如果
- 如果
/app不存在且目标路径不以/结尾,例如:
1
COPY src /app
则
/app被视为文件名(若上级目录存在),否则 Docker 也会创建缺失的目录结构再复制。- 如果
验证
示例 1:复制目录
1 | COPY ./config /opt/app/conf/ |
如果 /opt/app/conf/ 不存在,Docker 会创建整个路径 /opt/app/conf/。
示例 2:复制单个文件
1 | COPY ./my.conf /etc/nginx/my.conf |
如果 /etc/nginx/ 不存在,也会被自动创建,然后再放进去。
⚠️ 注意事项
不会创建源路径:
COPY只会创建目标路径。自动创建的目录权限:
- 默认继承当前镜像的
WORKDIR或根目录/的权限; - 可以通过
RUN mkdir -p /path && chown user:user /path预设权限。
- 默认继承当前镜像的
推荐习惯:
对生产镜像或权限敏感场景,显式创建目录并设置权限,例如:1
2RUN mkdir -p /app/conf && chown appuser:appuser /app/conf
COPY conf/ /app/conf/
Dockerfile 中 COPY / ADD 行为流程图
flowchart TD
A[Docker build 开始] --> B[执行 COPY / ADD 指令]
B --> C{源路径存在?}
C -- 否 --> D[构建失败
Source not found]
C -- 是 --> E{目标路径存在?}
E -- 是 --> F{目标是目录?}
F -- 是 --> G[复制内容进入目录]
F -- 否 --> H[覆盖或创建目标文件]
E -- 否 --> I[自动创建目标目录结构]
I --> G
G --> J[写入镜像层]
H --> J
J --> K[构建继续下一层]
可以这样理解构建过程:
- 源文件必须存在,否则构建直接失败;目标路径不存在时,Docker 会帮你递归创建目录,然后再复制文件;
- 如果目标已经存在,就根据是目录还是文件决定是“放进去”还是“覆盖”。