Dockerfile में RUN और CMD के बीच अंतर


294

मैं इस बारे में उलझन में हूं कि मुझे कब CMDबनाम का उपयोग करना चाहिए RUN। उदाहरण के लिए, बैश / शेल कमांड को निष्पादित करने के लिए (यानी ls -la) मैं हमेशा उपयोग करूंगा CMDया क्या कोई ऐसी स्थिति है जहां मैं उपयोग करूंगा RUN? इन दो समान Dockerfileनिर्देशों के बारे में सर्वोत्तम प्रथाओं को समझने की कोशिश कर रहा है ।


जवाबों:


426

RUN एक इमेज बिल्ड स्टेप है, एक RUNकमांड के बाद कंटेनर की स्थिति कंटेनर इमेज के लिए प्रतिबद्ध होगी। Dockerfile में कई RUNचरण हो सकते हैं जो छवि बनाने के लिए एक दूसरे के ऊपर परत करते हैं।

सीएमडी वह कमांड है जिसे आप निर्मित छवि को लॉन्च करते समय डिफ़ॉल्ट रूप से कंटेनर को निष्पादित करते हैं। एक Dockerfile केवल CMDपरिभाषित अंतिम का उपयोग करेगा । CMDजब साथ एक कंटेनर से शुरू होने अधिरोहित जा सकता है docker run $image $other_command

ENTRYPOINT भी बारीकी से संबंधित है CMDऔर जिस तरह से एक कंटेनर एक छवि शुरू होता है संशोधित कर सकते हैं।


15
आप RUNअपने पर्यावरण को स्थापित करने के लिए सभी आवश्यक कार्य करते हैं, और आपके (केवल) सीएमडी ने अपने कंटेनर में चल रही प्रक्रिया को लॉन्च किया है, उदाहरण के लिए, nginx के लिए, github.com/nginxinc/docker-nginx/blob// से लाइन निकालें और आप लाइन देखेंCMD ["nginx", "-g", "daemon off;"]
user2915097

"एक डॉकरफाइल में केवल एक सीएमडी हो सकता है" - तकनीकी रूप से सच नहीं है, लेकिन प्रभावी रूप से सभी को अनदेखा किया जाएगा। जिंजरबेर का उत्तर देखें।
कोलम भंडाल

"एक डॉकरफाइल केवल अंतिम CMD परिभाषित का उपयोग करेगा"? वास्तव में, अंतिम सीएमडी परिभाषित एक कंटेनर के रूप में छवि को लॉन्च करने में उपयोग किया जाएगा, है ना?
पौल

1
हाँ @paulcheung dockerfile में अंतिम कमांड छवि के लिए लिखी गई है और जब आप निर्मित छवि को लॉन्च करते हैं तो कंटेनर डिफ़ॉल्ट रूप से निष्पादित होता है।
मैट

126

RUN - जब हम डॉकटर छवि बनाते हैं तो कमांड ट्रिगर्स।

CMD - कमांड ट्रिगर करते समय हम निर्मित डॉकटर इमेज को लॉन्च करते हैं।


67

मुझे यह लेख उनके बीच के अंतर को समझने में बहुत मददगार लगा:

RUN - RUN निर्देश आपको इसके लिए आवश्यक अपने एप्लिकेशन और पैकेजों को स्थापित करने की अनुमति देता है। यह वर्तमान छवि के शीर्ष पर किसी भी कमांड को निष्पादित करता है और परिणामों को कम करके एक नई परत बनाता है। अक्सर आपको Dockerfile में कई RUN निर्देश मिलेंगे।

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


13

RUN - पायथन को स्थापित करें, आपके कंटेनर में अब अजगर अपनी छवि
CMD में जल गया है - अजगर hello.py, अपनी पसंदीदा स्क्रिप्ट चलाएँ


CMD - पायथन स्थापित करें, मेरा कंटेनर अब अपनी छवि में जले हुए अजगर को नहीं दिखा रहा है?
कार्लोस फॉन्टेस

RUN अजगर की एक छवि परत बनाएगा, CMD बस कमांड को निष्पादित करेगा छवि नहीं बनाएँ
रोहित सालेचा

8

RUN कमांड: RUN कमांड मूल रूप से डिफॉल्ट कमांड को निष्पादित करता है, जब हम छवि का निर्माण कर रहे होते हैं। यह अगले चरण के लिए छवि परिवर्तन भी करेगा।

नई छवि बनाने की प्रक्रिया में सहायता के लिए 1 से अधिक RUN कमांड हो सकते हैं।

CMD कमांड: CMD कमांड नए कंटेनर के लिए डिफ़ॉल्ट कमांड सेट करेगा। इसे बिल्ड टाइम पर निष्पादित नहीं किया जाएगा।

यदि docker फ़ाइल में 1 से अधिक CMD कमांड हैं, तो उनमें से सभी को पिछले एक को छोड़कर अनदेखा कर दिया जाता है। चूंकि यह कमांड कुछ भी निष्पादित नहीं करेगा, लेकिन बस डिफ़ॉल्ट कमांड सेट करेगा।


6

नोट: RUN को CMD के साथ भ्रमित न करें। RUN वास्तव में एक कमांड चलाता है और परिणाम देता है; सीएमडी बिल्ड टाइम पर कुछ भी निष्पादित नहीं करता है, लेकिन छवि के लिए इच्छित कमांड को निर्दिष्ट करता है।

docker फ़ाइल संदर्भ से

https://docs.docker.com/engine/reference/builder/#cmd


4

RUN : कई हो सकते हैं, और इसका उपयोग बिल्ड प्रोसेस में किया जाता है , जैसे कई लाइब्रेरी स्थापित करें

CMD : केवल 1 हो सकता है, जो कि आपका एग्जीक्यूट स्टार्ट पॉइंट (जैसे ["npm", "start"], ["node", "app.js"]) है


2

RUN और CMD पर पर्याप्त उत्तर दिए गए हैं । मैं केवल ENTRYPOINT पर कुछ शब्द जोड़ना चाहता हूंCMD तर्कों को कमांड लाइन तर्कों द्वारा अधिलेखित किया जा सकता है, जबकि ENTRYPOINT तर्क हमेशा उपयोग किए जाते हैं।

यह लेख जानकारी का एक अच्छा स्रोत है।


2

मौजूदा उत्तर इस प्रश्न को देखने वाले किसी भी व्यक्ति को सबसे अधिक कवर करते हैं। तो मैं सिर्फ CMD और RUN के लिए कुछ आला क्षेत्रों को कवर करूंगा।

CMD: डुप्लिकेट्स अनुमत हैं लेकिन व्यर्थ हैं

जिंजरब्रेड एक महत्वपूर्ण बिंदु बनाता है: यदि आप एक से अधिक सीएमडी में रखते हैं तो आपको कोई त्रुटि नहीं मिलेगी - लेकिन ऐसा करना बेकार है। मैं एक उदाहरण के साथ विस्तार करना चाहता हूं:

FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"

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

निष्पादित सीएमडी 2

जिस तरह से मुझे लगता है कि यह है कि "सीएमडी" पूरी छवि के लिए एक एकल वैश्विक चर स्थापित कर रहा है, इसलिए क्रमिक "सीएमडी" कथन किसी भी पिछले को उस वैश्विक चर को लिखते हैं, और अंतिम छवि में जो बनाया गया है। पिछले एक जीत लिखने के लिए। चूँकि एक डॉकरीफाइल ऊपर से नीचे तक के क्रम में निष्पादित होता है, हम जानते हैं कि सबसे नीचे का सीएमडी है जो इस अंतिम "राइट" (रूपक से बोलना) को प्राप्त करता है।

RUN: इमेजेज कैश्ड हैं तो कमांड एक्सेक्यूट नहीं कर सकते

RUN के बारे में नोटिस करने के लिए एक सूक्ष्म बिंदु यह है कि यह एक शुद्ध कार्य के रूप में माना जाता है, भले ही साइड-इफेक्ट्स हों, और इस प्रकार कैश किया गया हो। इसका मतलब यह है कि अगर RUN के कुछ साइड इफेक्ट्स हैं जो परिणामी छवि को नहीं बदलते हैं, और उस छवि को पहले ही कैश कर दिया गया है, तो RUN को फिर से निष्पादित नहीं किया जाएगा और इसलिए साइड इफेक्ट बाद के बिल्ड पर नहीं होंगे। उदाहरण के लिए, इस डॉकरीफाइल को लें:

FROM busybox
RUN echo "Just echo while you work"

पहली बार इसे चलाने पर, आपको अलग-अलग अल्फ़ान्यूमेरिक आईडी के साथ इस तरह का आउटपुट मिलेगा:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest

ध्यान दें कि उपरोक्त में इको स्टेटमेंट निष्पादित किया गया था। दूसरी बार जब आप इसे चलाते हैं, तो यह कैश का उपयोग करता है, और आपको बिल्ड के आउटपुट में कोई प्रतिध्वनि दिखाई नहीं देगी:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Using cache
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.