Câu hỏi Sự khác nhau giữa lệnh `COPY` và` ADD` trong Dockerfile là gì?


Sự khác biệt giữa COPY và ADD lệnh trong một Dockerfile, và khi nào tôi sẽ sử dụng một cái khác?


COPY <src> <dest>

Hướng dẫn COPY sẽ sao chép các tệp mới từ <src> và thêm chúng vào   hệ thống tệp của vùng chứa trên đường dẫn <dest>


ADD <src> <dest>

Lệnh ADD sẽ sao chép các tệp mới từ <src> và thêm chúng vào   hệ thống tập tin của container trên đường dẫn <dest>.


1493
2017-07-25 14:31


gốc


Xem các phương pháp hay nhất: docs.docker.com/engine/userguide/eng-image/… - EricSonaron
Vào tháng 6 năm 2018, tham chiếu cho biết ADD thêm vào hình ảnh (tức là tệp tĩnh) trong khi COPY thêm vào vùng chứa (ví dụ: phiên bản thời gian chạy của hình ảnh). Chắc chắn điều này ngụ ý rằng COPY được thực hiện mỗi khi hình ảnh được Docker run'd, hoặc có lẽ đây chỉ đơn giản là một trường hợp của thuật ngữ không phù hợp? - Chris Robinson
Tôi nghĩ đó là thuật ngữ không nhất quán - Daniel Stevens


Các câu trả lời:


Bạn nên kiểm tra ADD và COPY tài liệu cho mô tả đầy đủ về hành vi của họ, nhưng tóm lại sự khác biệt chính là ADD có thể làm nhiều hơn COPY:

  • ADD cho phép <src> trở thành một URL
  • Nếu <src> thông số của ADD là một kho lưu trữ ở định dạng nén được công nhận, nó sẽ được giải nén

Lưu ý rằng Các phương pháp hay nhất để viết Dockerfiles đề xuất sử dụng COPY nơi sự kỳ diệu của ADD không được yêu cầu. Nếu không bạn (vì bạn phải tra cứu câu trả lời này) có thể sẽ ngạc nhiên vào một ngày nào đó khi bạn muốn sao chép keep_this_archive_intact.tar.gz vào thùng chứa của bạn, nhưng thay vào đó bạn phun nội dung vào hệ thống tệp của mình.


1494
2017-07-25 14:52



@patriciasz Có vẻ như cụm từ đó đã xuất hiện lần cuối trong v0.9.1. Cũng thế, github.com/docker-library/golang/issues/18 xác nhận rằng COPY là không phải hiện không được chấp nhận. - michielbdejong
... và theo Các phương pháp hay nhất để viết Dockerfiles, COPY không chỉ không được chấp nhận, nó thậm chí còn được đề xuất trên ADD (nếu có thể): "Đối với các mục khác (tệp, thư mục) không yêu cầu khả năng tự động trích xuất của ADD, bạn phải luôn sử dụng COPY". - ehdr
@ starikovs bạn luôn có thể chỉ sử dụng một linter hơn là đọc thực hành tốt nhất (github.com/RedCoolBeans/dockerlint) = -) Linter đó cảnh báo nếu thực hành này không được theo sau. - Spain Train
nó có thể không được chấp nhận vì việc trích xuất tự động của ADD không hoạt động liên tục tùy thuộc vào việc bạn có sử dụng url hay không. - xenoterracide
docs.docker.com/engine/userguide/eng-image/… - dimpiax


COPY Là

Giống như 'ADD', nhưng không có tar và xử lý URL từ xa.

Tài liệu tham khảo ngay từ mã nguồn.


296
2017-09-30 16:13





Có một số tài liệu chính thức về điểm đó: Các phương pháp hay nhất để viết Dockerfiles 

Vì kích thước hình ảnh quan trọng, sử dụng ADD để tìm nạp gói từ các URL từ xa không được khuyến khích mạnh mẽ; bạn nên sử dụng curl hoặc là wget thay thế. Bằng cách đó bạn có thể xóa các tệp mà bạn không còn cần sau khi chúng được trích xuất và bạn sẽ không phải thêm một lớp nào khác trong hình ảnh của mình.

RUN mkdir -p /usr/src/things \
  && curl -SL http://example.com/big.tar.gz \
    | tar -xJC /usr/src/things \
  && make -C /usr/src/things all

Đối với các mục khác (tệp, thư mục) không yêu cầu ADDKhả năng tự động trích xuất tar của bạn, bạn nên luôn sử dụng COPY.


116
2017-10-02 08:21



Xem thêm cam kết này từ tháng 8 Ở đâu chính Dockerfile cho Docker đã chuyển từ ADD thành COPY - michielbdejong
Docker nói để thích COPY, bởi vì nó minh bạch hơn. Từ Các thực tiễn tốt nhất của trình quản lý tệp Docker (2014-12-15): Although ADD and COPY are functionally similar, generally speaking, COPY is preferred. That’s because it’s more transparent than ADD. COPY only supports the basic copying of local files into the container, while ADD has some features that are not immediately obvious. - schemar


Từ tài liệu Docker:

ADD hoặc COPY

Mặc dù ADD và COPY có chức năng tương tự, nói chung, COPY được ưu tiên. Đó là bởi vì nó minh bạch hơn ADD. COPY chỉ hỗ trợ sao chép cơ bản các tệp cục bộ vào vùng chứa, trong khi ADD có một số tính năng (như chỉ trích tar cục bộ và hỗ trợ URL từ xa) không rõ ràng ngay lập tức. Do đó, cách sử dụng tốt nhất cho ADD là tự động khai thác tệp tar cục bộ vào hình ảnh, như trong ADD rootfs.tar.xz /.

Hơn: Các phương pháp hay nhất để viết Dockerfiles


95
2017-08-10 15:19





Nếu bạn muốn thêm xx.tar.gz vào /usr/local trong vùng chứa, giải nén nó, và sau đó loại bỏ gói nén vô dụng.

Đối với COPY:

COPY resources/jdk-7u79-linux-x64.tar.gz /tmp/
RUN tar -zxvf /tmp/jdk-7u79-linux-x64.tar.gz -C /usr/local
RUN rm /tmp/jdk-7u79-linux-x64.tar.gz

Cho thêm:

ADD resources/jdk-7u79-linux-x64.tar.gz /usr/local/

ADD hỗ trợ khai thác tar cục bộ. Bên cạnh đó, COPY sẽ sử dụng ba lớp, nhưng ADD chỉ sử dụng một lớp.


27
2018-04-25 07:07



Có lý do nào không chỉ là hai lớp? RUN tar -zxvf /tmp/jdk-7u79-linux-x64.tar.gz -C /usr/local && rm /tmp/jdk-7u79-linux-x64.tar.gz - Stephen C


Từ tài liệu Docker: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy

COPY chỉ hỗ trợ sao chép cơ bản các tệp cục bộ vào trong thùng chứa, trong khi ADD có một số tính năng (như khai thác tar cục bộ và hỗ trợ URL từ xa) không rõ ràng ngay lập tức Do đó, cách sử dụng tốt nhất cho ADD là tự động khai thác tệp tar cục bộ vào hình ảnh, như trong ADD rootfs.tar.xz /.

Nếu bạn có nhiều bước Dockerfile sử dụng các tệp khác nhau từ ngữ cảnh của bạn, hãy sao chép từng tệp riêng lẻ, thay vì tất cả cùng một lúc. Điều này sẽ đảm bảo rằng bộ nhớ cache của mỗi bước chỉ bị vô hiệu hóa (buộc phải chạy lại) nếu các tệp bắt buộc cụ thể thay đổi.

Ví dụ:

 COPY requirements.txt /tmp/
 RUN pip install --requirement /tmp/requirements.txt
 COPY . /tmp/

Kết quả trong ít hiệu lực bộ nhớ cache cho bước RUN, hơn nếu bạn đặt COPY. / tmp / trước khi nó.

Do kích thước hình ảnh quan trọng, việc sử dụng ADD để tìm nạp gói từ các URL từ xa được khuyến khích mạnh mẽ; bạn nên sử dụng curl hoặc wget thay thế. Bằng cách đó, bạn có thể xóa các tệp bạn không còn cần sau khi chúng được trích xuất và bạn sẽ không phải thêm một lớp khác vào hình ảnh của mình. Ví dụ, bạn nên tránh làm những việc như:

 ADD http://example.com/big.tar.xz /usr/src/things/
 RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
 RUN make -C /usr/src/things all

Và thay vào đó, hãy làm điều gì đó như:

 RUN mkdir -p /usr/src/things \
     && curl -SL htt,p://example.com/big.tar.xz \
     | tar -xJC /usr/src/things \
     && make -C /usr/src/things all

Đối với các mục khác (tệp, thư mục) không yêu cầu khả năng tự động trích xuất của ADD, bạn phải luôn sử dụng COPY. "


11
2018-06-12 05:29





Lưu ý quan trọng

Tôi đã phải sao chép và gỡ bỏ gói java trong hình ảnh docker của tôi. Khi tôi so sánh kích thước hình ảnh docker được tạo bằng ADD, kích thước này lớn hơn 180MB sau đó được tạo bằng COPY, tar -xzf * .tar.gz và rm * .tar.gz

Điều này có nghĩa rằng mặc dù ADD loại bỏ tệp tar, nó vẫn được giữ ở đâu đó. Và nó làm cho hình ảnh lớn !!


0
2018-06-07 08:00



Điều này vẫn đúng với phiên bản mới nhất của Docker? - Navin


COPY sao chép tệp / thư mục từ máy chủ của bạn vào hình ảnh của bạn.

ADD sao chép tệp / thư mục từ máy chủ của bạn vào hình ảnh của bạn, nhưng cũng có thể tìm nạp các URL từ xa, trích xuất các tệp TAR, v.v ...

Sử dụng COPY chỉ cần sao chép các tệp và / hoặc thư mục vào ngữ cảnh xây dựng.

Sử dụng ADD để tải xuống tài nguyên từ xa, giải nén tệp TAR, v.v.


0
2018-05-31 12:11





docker build -t {image name} -v {host directory}:{temp build directory} .

Đây là một cách khác để sao chép tệp vào một hình ảnh. Tùy chọn -v tạm thời tạo ra một ổ đĩa mà chúng ta đã sử dụng trong quá trình xây dựng.

Điều này khác với các ổ đĩa khác vì nó gắn kết một thư mục lưu trữ cho chỉ xây dựng. Các tập tin có thể được sao chép bằng lệnh cp tiêu chuẩn.

Ngoài ra, giống như curl và wget, nó có thể được chạy trong một lệnh stack (chạy trong một container duy nhất) và không nhân kích thước hình ảnh. ADD và COPY không được xếp chồng lên nhau vì chúng chạy trong một vùng chứa độc lập và các lệnh tiếp theo trên các tệp thực thi trong các vùng chứa bổ sung sẽ nhân kích thước hình ảnh:

Với các tùy chọn thiết lập như sau:

-v /opt/mysql-staging:/tvol

Sau đây sẽ thực hiện trong một thùng chứa:

RUN cp -r /tvol/mysql-5.7.15-linux-glibc2.5-x86_64 /u1 && \
    mv /u1/mysql-5.7.15-linux-glibc2.5-x86_64 /u1/mysql && \

    mkdir /u1/mysql/mysql-files && \
    mkdir /u1/mysql/innodb && \
    mkdir /u1/mysql/innodb/libdata && \
    mkdir /u1/mysql/innodb/innologs && \
    mkdir /u1/mysql/tmp && \

    chmod 750 /u1/mysql/mysql-files && \
    chown -R mysql /u1/mysql && \
    chgrp -R mysql /u1/mysql

-1
2017-09-23 19:32



Phiên bản docker nào bạn đang ở nơi bạn thấy tùy chọn đó? Nó không được ghi chép và không hoạt động trên máy khách 1.12.1 của tôi. - BMitch
Trên thực tế, tính năng này vẫn chưa được bao gồm trong bản phát hành chính và vẫn còn nhiều cuộc thảo luận về chủ đề, vì vậy chúng tôi không nên mong đợi nó trước một thời gian dài ... Xem báo cáo lỗi để biết thêm thông tin: github.com/docker/docker/issues/14080. - jwatkins
Vâng, không có tùy chọn như vậy (được kiểm tra trong phiên bản mới nhất 17.06). Câu trả lời này là sai lầm. unknown shorthand flag: 'v' in -v - Kirby
Nhận xét gây hiểu lầm thực sự - Guido van Steen