Dockerfile में 'COPY' और 'ADD' कमांड के बीच क्या अंतर है?


2194

Dockerfile में COPYऔर ADDकमांड के बीच क्या अंतर है , और मैं एक दूसरे पर कब इस्तेमाल करूंगा?

COPY <src> <dest>

COPY निर्देश नई फ़ाइलों को कॉपी करेगा <src>और उन्हें पथ पर कंटेनर के फाइल सिस्टम में जोड़ देगा<dest>

ADD <src> <dest>

ADD निर्देश नई फ़ाइलों को कॉपी करेगा <src>और उन्हें पथ पर कंटेनर के फाइल सिस्टम में जोड़ देगा <dest>


11
सर्वोत्तम अभ्यास देखें: docs.docker.com/engine/userguide/eng-image/…
EricSonaron

9
जून 2018 के अनुसार संदर्भ कहता है कि ADD छवि में जुड़ जाता है (यानी एक स्थिर फ़ाइल) जबकि COPY कंटेनर में जुड़ जाता है (यानी छवि का रनटाइम उदाहरण)। निश्चित रूप से इसका तात्पर्य यह है कि हर बार जब छवि डॉक रनर है, तो COPY को निष्पादित किया जाता है, या शायद यह केवल असंगत शब्दावली का मामला है?
क्रिस रॉबिन्सन

14
मुझे लगता है कि यह असंगत शब्दावली है
डैनियल स्टीवंस

6
@ क्रिसहॉबिन्सन, इसे COPYचलाने के लिए हर बार निष्पादित करना असंभव होगा , क्योंकि यह आवश्यक नहीं है कि सामग्री को हथियाने के लिए मूल संदर्भ तक पहुंच हो।
केन विलियम्स

जवाबों:


2165

आपको उनके व्यवहारों के अधिक विस्तृत विवरण के लिए दस्तावेज़ ADDऔर COPYदस्तावेज़ की जांच करनी चाहिए , लेकिन संक्षेप में, प्रमुख अंतर यह है कि इससे ADDअधिक क्या हो सकता है COPY:

  • ADD<src>एक URL होने की अनुमति देता है
  • टिप्पणियों का उल्लेख करते हुए, ADD दस्तावेज में कहा गया है कि:

    यदि किसी मान्यताप्राप्त संपीड़न प्रारूप (पहचान, gzip, bzip2 या xz) में एक स्थानीय टार संग्रह है, तो यह एक निर्देशिका के रूप में अनपैक्ड है। दूरस्थ URL के संसाधन विघटित नहीं होते हैं।

ध्यान दें कि Dockerfiles लिखने के लिए सर्वोत्तम प्रथाओं का उपयोग करने का सुझाव है COPYजहां जादू की ADDआवश्यकता नहीं है। अन्यथा, आप ( जब से आपको यह उत्तर देखना था ) किसी दिन आश्चर्यचकित होने की संभावना है जब आप keep_this_archive_intact.tar.gzअपने कंटेनर में कॉपी करने का मतलब रखते हैं , लेकिन इसके बजाय, आप अपने फाइल सिस्टम पर सामग्री स्प्रे करते हैं।


65
बस कुछ स्पष्ट करना चाहता था: एक .DT के लिए एक url के साथ ADD का उपयोग करते हुए .tz.gz फाइलसिस्टम के संग्रह को प्राप्त नहीं करता है (मैं सुनिश्चित करने के लिए अभी सही जाँच करता हूं और इसकी पुष्टि की गई है)
Cecile

42
यह आवश्यक जानकारी है और यह एक अपराध है कि आधिकारिक डोकरफाइल संदर्भ इस तरह से अंतर को स्पष्ट नहीं करता है।
चेसो

1
यकीन नहीं, अगर यह एक छवि के लिए छवि के लिए अलग है। मैंने एक ज़िप फ़ाइल के लिए बिजीबॉक्स इमेज और ADD का उपयोग किया। यह बस गंतव्य निर्देशिका में बिना खोल दिए दिखाई दिया। मुझे लगता है, निष्कर्षण केवल टारबॉल के लिए होता है, लेकिन मैंने अब जाँच नहीं की है।
संतोष कुमार अर्जुनन

4
@SantoshKumarArjunan: डॉकर डॉक्स ADD और स्वचालित टैर निष्कर्षण के बारे में निम्नलिखित बताते हैं: If <src> is a local tar archive in a recognized compression format (identity, gzip, bzip2 or xz) then it is unpacked as a directory. Resources from remote URLs are not decompressed. डॉकर ADD
hmacias

1
COPY अनुमति देता है - From = <name | index>, जहां मुझे ADD के लिए समान समर्थन नहीं मिल सकता है
ब्रैंडन

474

COPY है

'ADD' के रूप में भी, लेकिन टार और रिमोट यूआरएल को संभालने के बिना।

स्रोत कोड से सीधे संदर्भ ।


15
क्या मैं इसे सही ढंग से देखता हूं: गैर-मौजूदा निर्देशिकाADD भी बनाता है । इस प्रकार, हालांकि, इस पूरे धागे में किसी भी तरह से हतोत्साहित किया गया है, इसका एक फायदा है COPYक्योंकि आपको mkdirकुछ टाइप करने और बचाने की ज़रूरत नहीं है
eli

3
COPY वह भी करता है @eli
bhordupur

अब तक की सर्वश्रेष्ठ व्याख्या। यह स्वीकृत उत्तर क्यों नहीं है?
xdevx32

141

उस बिंदु पर कुछ आधिकारिक दस्तावेज़ीकरण हैं: डॉकफ़िल्स लिखने के लिए सर्वश्रेष्ठ अभ्यास

क्योंकि छवि आकार मायने रखता है, ADDदूरस्थ URL से संकुल लाने के लिए दृढ़ता से हतोत्साहित किया जाता है; आपको इसका उपयोग करना चाहिए curlया wgetइसके बजाय। इस तरह आप उन फ़ाइलों को हटा सकते हैं जिनकी अब आपको आवश्यकता नहीं है, उन्हें निकालने के बाद और आपको अपनी छवि में एक और परत नहीं जोड़ना होगी।

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

अन्य वस्तुओं (फ़ाइलों, निर्देशिकाओं) के लिए, जिन्हें ADDटार ऑटो-निष्कर्षण क्षमता की आवश्यकता नहीं है , आपको हमेशा उपयोग करना चाहिए COPY



18
डॉकर पसंद करने के लिए कहते हैं COPY, क्योंकि यह अधिक पारदर्शी है। से डोकर फ़ाइल उत्तम आचरण : (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

115

डॉकर डॉक्स से:

ADD या COPY

हालांकि ADD और COPY कार्यात्मक रूप से समान हैं, आम तौर पर बोलना, COPY को पसंद किया जाता है। ऐसा इसलिए है क्योंकि यह ADD से अधिक पारदर्शी है। COPY केवल कंटेनर में स्थानीय फ़ाइलों की मूल प्रतिलिपि का समर्थन करता है, जबकि ADD में कुछ विशेषताएं हैं (जैसे स्थानीय-केवल टार निष्कर्षण और दूरस्थ URL समर्थन) जो तुरंत स्पष्ट नहीं हैं। नतीजतन, ADD के लिए सबसे अच्छा उपयोग छवि में स्थानीय टार फ़ाइल ऑटो-निष्कर्षण है, जैसा कि ADD rootfs.tar.xx/ में है।

अधिक: डॉकफाइल्स लिखने के लिए सर्वोत्तम अभ्यास


46

यदि आप एक xx.tar.gz /usr/localकंटेनर में जोड़ना चाहते हैं , तो उसे अनज़िप करें, और फिर बेकार संपीड़ित पैकेज को हटा दें।

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

जोड़ने के लिए:

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

ADD स्थानीय-केवल टार निष्कर्षण का समर्थन करता है। इसके अलावा, COPY तीन परतों का उपयोग करेगा, लेकिन ADD केवल एक परत का उपयोग करता है।


3
किसी भी कारण से सिर्फ दो परतें ही क्यों? RUN tar -zxvf /tmp/jdk-7u79-linux-x64.tar.gz -C /usr/local && rm /tmp/jdk-7u79-linux-x64.tar.gz
स्टीफन सी।

24

COPY आपके मेजबान से आपकी छवि के लिए एक फ़ाइल / निर्देशिका की प्रतिलिपि बनाता है।

ADD आपकी छवि से होस्ट / फ़ाइल की प्रतिलिपि बनाता है, लेकिन दूरस्थ URL भी प्राप्त कर सकता है, TAR फ़ाइलों को निकाल सकता है, आदि ...

उपयोग COPYबिल्ड संदर्भ में बस फ़ाइलों और / या निर्देशिकाओं की प्रतिलिपि बनाने के लिए ।

ADDदूरस्थ संसाधनों को डाउनलोड करने, TAR फ़ाइलों को निकालने, आदि के लिए उपयोग करें ।


4
मेरे जैसे एक noob के लिए सही स्पष्टीकरण
uneq95

17

डॉकर डॉक्स से: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy

"हालांकि ADD और COPY कार्यात्मक रूप से समान हैं, आम तौर पर बोलना, COPY को प्राथमिकता दी जाती है। ऐसा इसलिए है क्योंकि यह ADD से अधिक पारदर्शी है। COPY केवल कंटेनर में स्थानीय फ़ाइलों की मूल प्रतिलिपि का समर्थन करता है, जबकि ADD में कुछ विशेषताएं हैं (जैसे स्थानीय-केवल टार निष्कर्षण। दूरस्थ URL समर्थन) जो तुरंत स्पष्ट नहीं हैं। परिणामस्वरूप, ADD के लिए सबसे अच्छा उपयोग छवि में स्थानीय टार फाइल ऑटो-निष्कर्षण है, जैसा कि ADD rootfs.tar.xz / में है।

यदि आपके पास एक से अधिक Dockerfile चरण हैं जो आपके संदर्भ से अलग-अलग फ़ाइलों का उपयोग करते हैं, तो उन्हें व्यक्तिगत रूप से कॉपी करें, बजाय एक बार में। यह सुनिश्चित करेगा कि प्रत्येक चरण का बिल्ड कैश केवल अमान्य है (यदि चरण को फिर से चलाने के लिए मजबूर किया जाता है) यदि विशेष रूप से आवश्यक फाइलें बदल जाती हैं।

उदाहरण के लिए:

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

यदि आप COPY डालते हैं, तो RUN चरण के लिए कम कैश अमान्य परिणाम हैं। / tmp / इससे पहले।

क्योंकि छवि आकार मायने रखता है, दूरस्थ URL से संकुल लाने के लिए ADD का उपयोग करने से दृढ़ता से हतोत्साहित किया जाता है; आपको इसके बजाय कर्ल या विग का उपयोग करना चाहिए। इस तरह से आप उन फ़ाइलों को हटा सकते हैं जिनकी अब आपको आवश्यकता नहीं है, उन्हें निकाले जाने के बाद और आपको अपनी छवि में एक और परत नहीं जोड़ना होगी। उदाहरण के लिए, आपको चीजों को करने से बचना चाहिए:

 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

और इसके बजाय, कुछ ऐसा करें:

 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

अन्य मदों (फ़ाइलों, निर्देशिकाओं) के लिए जिन्हें ADD की टार-ऑटो-निष्कर्षण क्षमता की आवश्यकता नहीं है, आपको हमेशा COPY का उपयोग करना चाहिए। "


7

स्रोत: https://nickjanetakis.com/blog/docker-tip-2-the-difference-between-copy-and-add-in-a-dockerile :

COPY और ADD, दोनों डॉकफेराइल निर्देश हैं जो समान उद्देश्यों को पूरा करते हैं। वे आपको एक विशिष्ट स्थान से डॉक छवि में फ़ाइलों को कॉपी करने देते हैं।

COPY एक src और गंतव्य में ले जाता है। यह केवल आपको अपने होस्ट (डॉकर छवि बनाने वाली मशीन) से एक स्थानीय फ़ाइल या निर्देशिका में प्रतिलिपि बनाता है जो डॉक छवि में ही है।

ADD आपको वह भी करने देता है, लेकिन यह 2 अन्य स्रोतों का भी समर्थन करता है। सबसे पहले, आप एक स्थानीय फ़ाइल / निर्देशिका के बजाय एक URL का उपयोग कर सकते हैं। दूसरे, आप स्रोत से सीधे टार फ़ाइल को गंतव्य में निकाल सकते हैं

ADD के लिए एक मान्य उपयोग मामला तब है जब आप अपनी डॉकर छवि में एक विशिष्ट निर्देशिका में एक स्थानीय टार फाइल निकालना चाहते हैं।

यदि आप अपनी डोकर छवि में स्थानीय फ़ाइलों की नकल कर रहे हैं, तो हमेशा COPY का उपयोग करें क्योंकि यह अधिक स्पष्ट है।


7

Dockerfile बनाते समय, दो कमांड्स होते हैं जिनका उपयोग आप फ़ाइलों / निर्देशिकाओं को कॉपी करने के लिए कर सकते हैं - ADDऔर COPY। यद्यपि उनके कार्य के दायरे में मामूली अंतर हैं, वे अनिवार्य रूप से एक ही कार्य करते हैं।

तो, हमारे पास दो कमांड क्यों हैं, और हम कैसे जानते हैं कि एक या दूसरे का उपयोग कब करना है?

डॉकटर ADDकमांड

आइए यह देखते हुए शुरू करें कि ADDकमांड से पुराना है COPY। डॉकर प्लेटफॉर्म के लॉन्च के बाद से, ADDनिर्देश इसके कमांड की सूची का हिस्सा रहा है।

कमांड निर्दिष्ट कंटेनर के फाइल सिस्टम में फाइलों / निर्देशिकाओं को कॉपी करता है।

ADDकमांड के लिए मूल सिंटैक्स है:

ADD <src> … <dest>

इसमें वह स्रोत शामिल है जिसे आप कॉपी करना चाहते हैं ( <src>) गंतव्य के बाद आप इसे स्टोर करना चाहते हैं ( <dest>)। यदि स्रोत एक निर्देशिका है, तो ADDइसके अंदर सब कुछ कॉपी करता है (फाइल सिस्टम मेटाडेटा सहित)।

उदाहरण के लिए, यदि फ़ाइल स्थानीय रूप से उपलब्ध है और आप इसे किसी छवि की निर्देशिका में जोड़ना चाहते हैं, तो आप टाइप करें:

ADD /source/file/path  /destination/path

ADDURL से फ़ाइलों की प्रतिलिपि भी बना सकते हैं। यह एक बाहरी फ़ाइल डाउनलोड कर सकता है और इसे वांछित गंतव्य पर कॉपी कर सकता है। उदाहरण के लिए:

ADD http://source.file/url  /destination/path

एक अतिरिक्त विशेषता यह है कि यह संपीड़ित फ़ाइलों की प्रतिलिपि बनाता है, स्वचालित रूप से दिए गए गंतव्य में सामग्री निकाल रहा है। यह सुविधा केवल स्थानीय रूप से संग्रहीत संपीड़ित फ़ाइलों / निर्देशिकाओं पर लागू होती है।

ADD source.file.tar.gz /temp

ध्यान रखें कि आप URL से एक संपीड़ित फ़ाइल / निर्देशिका को डाउनलोड और निकाल नहीं सकते हैं। स्थानीय फ़ाइल सिस्टम में कॉपी करते समय कमांड बाहरी पैकेजों को अनपैक नहीं करता है।

डॉकटर COPYकमांड

कुछ कार्यक्षमता के मुद्दों के कारण, डॉकटर को सामग्री की नकल के लिए एक अतिरिक्त आदेश पेश करना पड़ा - COPY

इसके निकट से संबंधित ADDकमांड के विपरीत , COPYकेवल एक ही नियत कार्य है। इसकी भूमिका अपने मौजूदा प्रारूप में निर्दिष्ट स्थान पर फ़ाइलों / निर्देशिकाओं की नकल करना है। इसका मतलब है कि यह एक संपीड़ित फ़ाइल निकालने के साथ सौदा नहीं करता है, बल्कि इसे इस रूप में कॉपी करता है।

निर्देश का उपयोग केवल स्थानीय रूप से संग्रहीत फ़ाइलों के लिए किया जा सकता है। इसलिए, आप अपने कंटेनर में बाहरी फ़ाइलों को कॉपी करने के लिए URL के साथ इसका उपयोग नहीं कर सकते हैं।

COPYनिर्देश का उपयोग करने के लिए , मूल कमांड प्रारूप का पालन करें:

स्रोत में टाइप करें और जहाँ आप सामग्री को निकालने के लिए कमांड चाहते हैं:

COPY <src> … <dest> 

उदाहरण के लिए:

COPY /source/file/path  /destination/path 

कौन सी कमांड का उपयोग करना है? (सर्वश्रेष्ठ अभ्यास)

जिन परिस्थितियों में COPYकमांड को पेश किया गया था, उन्हें देखते हुए , यह स्पष्ट है कि रखना ADDएक आवश्यकता का विषय था। डॉकर ने एक आधिकारिक दस्तावेज जारी किया जिसमें डॉकफाइल्स लिखने के लिए सर्वोत्तम प्रथाओं का उल्लेख किया गया है, जो स्पष्ट रूप से ADDकमांड का उपयोग करने के खिलाफ सलाह देता है ।

डॉकर के आधिकारिक दस्तावेज़ीकरण नोट्स जो COPYहमेशा गो-टू इंस्ट्रक्शन होने चाहिए क्योंकि यह अधिक पारदर्शी है ADD

यदि आपको एक कंटेनर में स्थानीय बिल्ड संदर्भ से कॉपी करने की आवश्यकता है, तो उपयोग करने के लिए छड़ी COPY

डॉकर टीम ADDएक यूआरएल से पैकेज को डाउनलोड करने और कॉपी करने के लिए दृढ़ता से हतोत्साहित करती है । इसके बजाय, यह सुरक्षित और RUNकमांड के भीतर wget या कर्ल का उपयोग करने के लिए अधिक कुशल है । ऐसा करने से, आप एक अतिरिक्त छवि परत बनाने और स्थान बचाने से बचते हैं।


4

महत्वपूर्ण लेख

मुझे COPYअपनी डॉक इमेज में जावा पैकेज को और अनटार करना पड़ा । जब मैंने ADD के उपयोग से बनाए गए docker की इमेज साइज की तुलना की तो यह COPY, tarxzzf * .tar.gz और rm * .tar.gz का उपयोग करते हुए बनाए गए 180MB से बड़ा था।

इसका मतलब यह है कि यद्यपि ADD टार फाइल को हटा देता है, फिर भी इसे कहीं रखा गया है। और इसकी छवि को बड़ा बना रही है !!


क्या यह अभी भी डॉकर के नवीनतम संस्करण के लिए सही है?
नवीन

3

चूंकि डॉकटर 17.05 COPYका उपयोग मल्टी-स्टेज बिल्ड--from में ध्वज के साथ किया जाता है, जो पिछले बिल्ड चरणों से लेकर वर्तमान बिल्ड स्टेज तक की कलाकृतियों को कॉपी करने के लिए होता है।

से प्रलेखन

वैकल्पिक रूप से COPY एक ध्वज को स्वीकार करता है --from=<name|index>जिसे स्रोत स्थान को पिछले बिल्ड चरण (FROM .. AS के साथ बनाया गया) के रूप में उपयोग किया जा सकता है जो उपयोगकर्ता द्वारा भेजे गए बिल्ड संदर्भ के बजाय उपयोग किया जाएगा।


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

यह एक छवि में फ़ाइलों को कॉपी करने का एक और तरीका है। -V विकल्प अस्थायी रूप से एक वॉल्यूम बनाता है जिसका उपयोग हमने निर्माण प्रक्रिया के दौरान किया था।

यह अलग है कि अन्य वॉल्यूम क्योंकि यह केवल बिल्ड के लिए एक होस्ट निर्देशिका को मापता है। मानक cp कमांड का उपयोग करके फ़ाइलों को कॉपी किया जा सकता है।

इसके अलावा, कर्ल और विग की तरह, इसे एक कमांड स्टैक (एक कंटेनर में रन) में चलाया जा सकता है और छवि आकार को गुणा नहीं किया जा सकता है। ADD और COPY स्टैकेबल नहीं हैं क्योंकि वे एक स्टैंडअलोन कंटेनर में चलते हैं और बाद में उन फाइलों पर कमांड करते हैं जो अतिरिक्त कंटेनरों में निष्पादित होते हैं, छवि का आकार गुणा करेंगे:

इस प्रकार सेट किए गए विकल्पों के साथ:

-v /opt/mysql-staging:/tvol

निम्नलिखित एक कंटेनर में निष्पादित होगा:

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
उस विकल्प को देखने पर आप क्या कर रहे हैं? यह प्रलेखित नहीं है और मेरे 1.12.1 क्लाइंट पर काम नहीं करता है।
21

2
दरअसल, यह फीचर अभी भी मुख्य रिलीज में शामिल नहीं किया गया है, और अभी भी इस विषय पर बहुत चर्चा है, इसलिए हमें लंबे समय से पहले इसकी उम्मीद नहीं करनी चाहिए ... अधिक जानकारी के लिए बग रिपोर्ट देखें: github.com/ डोकर / डोकर / मुद्दों / 14080
jwatkins

1
हाँ, ऐसा कोई विकल्प नहीं है (नवीनतम संस्करण 17.06 में जांचा गया है)। यह उत्तर भ्रामक है। unknown shorthand flag: 'v' in -v
किर्बी

भ्रामक टिप्पणी वास्तव में
Guido van Steen

उत्तर में डॉकटर संस्करणों का यहां कोई लेना-देना नहीं था, कृपया यदि आप कर सकते हैं, तो सीधे प्रश्न का उत्तर दें :), यह आसानी से उत्तर देने वाला उत्तर है।
माजिद अली खान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.