copy指令用于将构建上下文中的文件或目录复制到镜像中,支持单文件、多文件、目录、通配符复制,可指定--chown和--chmod参数设置归属与权限,并支持多阶段构建中的跨阶段复制。

COPY 指令是 Dockerfile 里最常用、也最该优先使用的文件复制方式,它只做一件事:把构建上下文里的文件或目录,原样复制进镜像。不自动解压、不拉远程 URL、不隐藏逻辑——简单可靠,适合绝大多数场景。
基础用法:路径和上下文要对得上
源路径(docker build -f Dockerfile . 时那个 . 所指的目录及其子目录。目标路径(/app/),也可以是相对于 WORKDIR 的相对路径(如 ./src)。
- 复制单个文件:
COPY package.json /usr/src/app/ - 复制多个文件到同一目录:
COPY main.go go.mod go.sum /app/ - 复制整个目录内容(不含目录本身):
COPY ./src /app/src - 用通配符批量复制:
COPY *.py /app/或COPY config?.yml /app/(? 匹配单个字符)
权限与归属:复制后直接设好用户和权限
默认情况下,COPY 会保留源文件的读写执行权限、修改时间等元数据。但生产环境通常需要更精细控制,这时可用两个可选参数:
-
--chown=www-data:www-data:指定文件所有者和组(要求该用户/组已在镜像中存在,比如通过RUN useradd创建) -
--chmod=644:直接设置文件权限(类似 chmod 命令,Docker 20.10+ 支持) - 示例:
COPY --chown=node:node --chmod=755 start.sh /usr/local/bin/start.sh
多阶段构建中跨阶段复制
在多阶段构建中,COPY 不仅能复制本地文件,还能从前面的构建阶段“取”产物,这是精简最终镜像的关键。
- 先定义一个构建阶段(如
FROM golang AS builder),编译出二进制文件 - 再切换到运行阶段(如
FROM alpine),用COPY --from=builder /app/myapp /usr/bin/myapp把编译结果拿过来 - 这样最终镜像里只有可执行文件,没有 Go 编译器、源码、依赖包等冗余内容
常见坑点和注意事项
COPY 看似简单,但几个细节容易导致构建失败或行为异常:
- 不能复制构建上下文之外的文件(比如
COPY /home/user/file.txt /tmp/会报错) - 目标路径不存在时,Docker 会自动创建中间目录,但不会自动创建父目录的父目录(比如
/a/b/c不存在,COPY x /a/b/c/d会成功;但/a/b若完全不存在,也可能因路径解析规则而失败,建议显式RUN mkdir -p /a/b/c) - 目录复制时,
COPY dir/ dest/复制的是dir/下的内容;COPY dir dest(末尾无斜杠)则把dir整个目录复制为dest - 如果想自动解压 tar 包或下载远程资源,请用
ADD;但除非必要,推荐坚持用COPY,保持语义清晰、行为可预测











