COPY 路径语义是什么
COPY 的源路径相对构建上下文根目录解析,不能用上级目录跳出上下文;目标路径若写成绝对路径就按绝对路径落,写成相对路径则相对 WORKDIR。最容易踩的是目录语义:复制目录时复制的是目录里的内容,而不是目录本身,因此目标路径是否带结尾斜杠、是否已存在,会决定最终的文件布局。
基本信息
| 源路径基准 | 构建上下文根目录,不能用 ../ 跳出 |
|---|---|
| 目标路径基准 | 绝对路径,或相对当前 WORKDIR |
| 目录语义 | 复制目录内容而非目录自身 |
| 文件到目录 | 目标以斜杠结尾时复制进该目录并保留原文件名 |
| 文件到新路径 | 目标不存在且父目录存在时被当作重命名 |
| 相关指令 | WORKDIR 影响相对目标;.dockerignore 影响可见源文件 |
典型使用场景
- 把配置目录整体复制到镜像内固定位置
- 把构建产物从多阶段的上一个阶段搬运到最终镜像
- 需要精确控制文件落地名字(改名)时的写法
- 排查文件缺失:确认是路径写错还是被 .dockerignore 排除
- 给复制的内容同时指定属主,避免运行用户没有读权限
几种典型写法
几种典型写法
# 文件到文件:目标已存在或被视作完整路径时按文件处理
COPY config/app.yaml /etc/app/app.yaml
# 目录内容到目标目录:复制的是 config 里的内容,不含 config 这一层
COPY config/ /etc/app/config/
# 文件到目录:目标以斜杠结尾,保留原文件名
COPY app.yaml /etc/app/
# 复制多个源到同一目标目录(目标必须以斜杠结尾)
COPY package.json package-lock.json /app/
# 相对目标路径:相对 WORKDIR 展开,落地为 /srv/app/src
WORKDIR /srv/app
COPY ./src src路径落点速查
| 源 | 目标 | 结果 |
|---|---|---|
| ./src(目录) | /app/ | /app 下是 src 里的内容 |
| app.yaml(文件) | /etc/app/app.yaml | 落地为同名文件 |
| app.yaml(文件) | /etc/app/ | 落地为 /etc/app/app.yaml |
| a.yaml b.yaml | /app/ | 两个文件都进 /app |
| ../secret | 任意 | 构建报错:超出上下文 |
| 被 .dockerignore 排除的文件 | 任意 | 文件不存在,复制失败或内容缺失 |
不确定布局时,用一个临时容器验证最快:把镜像跑起来执行 ls -R 或 find 查看实际结构,比反复读文档猜规则可靠。
被 .dockerignore 排除的路径会从构建上下文里消失,COPY 时表现为「文件不存在」,但错误信息不一定指向忽略规则,排查时要同时看这两处。