Dockerfile पर WORKDIR का क्या मतलब है?


106

मैं डॉकर सीख रहा हूं। कई बार के लिए मैंने देखा है कि गया है Dockerfileहै WORKDIRआदेश:

FROM node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
EXPOSE 3000
CMD [ “npm”, “start” ] 

मैं तो बस छोड़ नहीं कर सकते WORKDIRऔर Copyऔर सिर्फ मेरी है Dockerfileअपने प्रोजेक्ट की जड़ में? इस दृष्टिकोण का उपयोग करने के डाउनसाइड क्या हैं?


बिल्ड टाइम पर आप डायरेक्टरी बदल करWORKDIR
Ultraviolet

1
@Ultraviolet क्या आप इसे समझा सकते हैं। मैं काफी नहीं मिल रहा हूँ
Le garcon

जवाबों:


118

प्रलेखन के अनुसार :

कार्य निर्देश किसी भी RUN, CMD, ENTRYPOINT, COPY और ADD निर्देशों के लिए कार्यशील निर्देशिका को सेट करता है, जो इसे Dockerfile में अनुसरण करते हैं। यदि कार्यकुशलता मौजूद नहीं है, तो इसे तब भी बनाया जाएगा, जब इसका उपयोग किसी भी बाद के डॉकरफ़ाइल निर्देश में नहीं किया गया हो।

इसके अलावा, डॉकर सर्वोत्तम प्रथाओं में यह आपको इसका उपयोग करने की सलाह देता है:

... आपको RUN cd ... && do-something, जैसे कि निर्देशों को लम्बा करने के बजाय WORKDIR का उपयोग करना चाहिए, जो पढ़ने, समस्या निवारण और बनाए रखने में कठिन हैं।

मैं इसे रखने का सुझाव दूंगा।

मुझे लगता है कि आप अपनी डॉकरीफाइल को कुछ इस तरह से रिफ्लेक्टर कर सकते हैं:

FROM node:latest
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD [ “npm”, “start” ] 

2
@MarioGil कृपया COPY प्रलेखन
जुलुमूल

1
जब मैं उपयोग करता हूं FROM ubuntu as builderऔर तब क्रमिक छवि का उपयोग COPYकरता है, तो क्या यह "पता है" मैंने "बिल्डर" छवि में काम का उपयोग किया है या मुझे यह मान लेना होगा (और निरपेक्ष पथ का उपयोग नहीं करना चाहिए)?
एलेक्स 75

के अनुसार डोकर प्रलेखन मैं कहूंगा कि यह रहता है WORKDIRमूल्य क्योंकि Dockerfile में एक अनुदेश भाग गया है इससे पहले कि आप चलाने के COPYएक
juanlumn

आपकी RUN mkdirआज्ञा आवश्यक नहीं है; यानी, उस लाइन को हटाया जा सकता है। प्रलेखन के अनुसार "यदि कार्यकुशलता मौजूद नहीं है, तो इसे तब भी बनाया जाएगा, जब इसका उपयोग किसी भी बाद के डॉकफ़र्ट निर्देश में नहीं किया गया हो।" - docs.docker.com/engine/reference/builder/#workdir
जामुनी

@Purplejacket जो सही है, मैं जवाब को अपडेट
करूंगा

60

आपको नहीं करना है

RUN mkdir -p /usr/src/app

आपके द्वारा निर्दिष्ट किए जाने पर यह अपने आप बन जाएगा WORKDIR

FROM node:latest
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD [ “npm”, “start” ] 

4
हालाँकि, कभी-कभी RUN mkdir की आवश्यकता होती है क्योंकि निर्देशिका बनाते समय WORKDIR USER का सम्मान नहीं करता है - github.com/moby/moby/issues/20295
8:17 पर जो बोएबेर

23
मैं इस तथ्य को पसंद करता हूं कि आपने निर्दिष्ट काम फ़ोल्डर को स्वचालित रूप से बना देगा।
जिंजरबायर

32

आप कंटेनर के अंदर की WORKDIRतरह सोच सकते हैं cd(यह कमांड को प्रभावित करता है जो बाद में RUNकमांड की तरह डॉकरफाइल में आता है )। यदि आपने WORKDIRऊपर अपने उदाहरण में हटा दिया है, RUN npm installतो काम नहीं करेगा क्योंकि आप /usr/src/appअपने कंटेनर के अंदर निर्देशिका में नहीं होंगे ।

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


3
यदि WORKDIRजोड़ा जाता है cd, COPYतो मूल उदाहरण में दो समान स्रोत और गंतव्य नहीं होंगे?
जोनास रोसेनकविस्ट

5
सं । कंटेनर के अंदरWORKDIR काम कर रहे डायरेक्टरी को प्रभावित करता है । मूल उदाहरण में, कंटेनर पर होस्ट (डॉकफेराइल के सापेक्ष पथ) COPYसे पहली प्रतियां । वास्तव में, उस विशेष आदेश पर कोई प्रभाव नहीं पड़ता है क्योंकि गंतव्य (कंटेनर के अंदर) एक रिश्तेदार पथ (पथ के साथ शुरू होता है ) का उपयोग नहीं कर रहा है । package.json /usr/src/app/package.json WORKDIR/
mkasberg

@ मस्कसबर्ग अगर ए की WORKDIRतरह काम करता है cd। तो क्या नीचे 2 स्निपेट बराबर है? WORKDIR /usr/src/app COPY package.json /usr/src/app/और WORKDIR /usr/src/app COPY package.json . धन्यवाद
kcatstack

1
हाँ, वे बराबर हैं।
mkasberg

1

WORKDIR लगाने से पहले। यहां काम गलत जगह पर है और इसका इस्तेमाल समझदारी से नहीं किया जाता है।

FROM microsoft/aspnetcore:2
COPY --from=build-env /publish /publish
WORKDIR /publish
ENTRYPOINT ["dotnet", "/publish/api.dll"]

हमने उपरोक्त कोड को सही स्थान पर काम करने के लिए सही किया और हटाकर निम्नलिखित कथनों को अनुकूलित किया /Publish

FROM microsoft/aspnetcore:2
WORKDIR /publish
COPY --from=build-env /publish .
ENTRYPOINT ["dotnet", "/api.dll"]

1
आपके पास api.dll का स्लैश इनफ़ेक्शन नहीं होना चाहिए क्योंकि यह कंटेनर की जड़ तक जाएगा
टिमोथी c

1

वैर को लक्ष्य निर्देशिका के नाम के रूप में उपयोग करने से सावधान रहें WORKDIR- ऐसा करने से परिणाम "घातक कुछ भी सामान्य नहीं हो सकता है"। IMO, यह भी इंगित करने के लायक है कि WORKDIRउसी तरह व्यवहार करता है mkdir -p <path>जैसे कि पथ के सभी तत्व बनाए जाते हैं यदि वे पहले से मौजूद नहीं हैं।

अद्यतन: मैंने चर संबंधित समस्या का सामना किया (ऊपर उल्लेख किया गया है) मल्टी-स्टेज बिल्ड चलाने के दौरान - अब यह प्रतीत होता है कि एक चर का उपयोग करना ठीक है - यदि यह (चर) "स्कोप" है "जैसे" निम्नलिखित में, तो दूसरा WORKDIRसंदर्भ विफल रहता है ...

FROM <some image>
ENV varname varval
WORKDIR $varname

FROM <some other image>
WORKDIR $varname

जबकि, यह इसमें सफल होता है ...

FROM <some image>
ENV varname varval
WORKDIR $varname

FROM <some other image>
ENV varname varval
WORKDIR $varname

.oO ( शायद यह डॉक्स में है और मैंने इसे याद किया है )


0

सावधान रहें कि आप कहाँ सेट हैं WORKDIRक्योंकि यह निरंतर एकीकरण प्रवाह को प्रभावित कर सकता है। उदाहरण के लिए, इसे सेट करने में /home/circleci/projectत्रुटि हो सकती है जैसे कि .sshया जो कुछ भी दूरस्थ दूरस्थ सेटअप समय पर कर रहा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.