पीटर ग्रिंगर के जवाब का विस्तार करते हुए मैं डॉक 17.05 के बाद से उपलब्ध मल्टी-स्टेज बिल्ड का उपयोग करने में सक्षम था । आधिकारिक पृष्ठ की स्थिति:
मल्टी-स्टेज बिल्ड के साथ, आप FROMअपने डॉकरीफाइल में कई स्टेटमेंट का उपयोग करते हैं । प्रत्येक FROMनिर्देश एक अलग आधार का उपयोग कर सकता है, और उनमें से प्रत्येक निर्माण का एक नया चरण शुरू करता है। आप चुनिंदा कलाकृतियों को एक चरण से दूसरे चरण में कॉपी कर सकते हैं, जो आपको अंतिम छवि में नहीं चाहिए।
इसे ध्यान में रखते हुए Dockerfileतीन बिल्ड चरणों को शामिल करने का मेरा उदाहरण है । यह ग्राहक वेब एप्लिकेशन की एक उत्पादन छवि बनाने के लिए है।
# Stage 1: get sources from npm and git over ssh
FROM node:carbon AS sources
ARG SSH_KEY
ARG SSH_KEY_PASSPHRASE
RUN mkdir -p /root/.ssh && \
chmod 0700 /root/.ssh && \
ssh-keyscan bitbucket.org > /root/.ssh/known_hosts && \
echo "${SSH_KEY}" > /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa
WORKDIR /app/
COPY package*.json yarn.lock /app/
RUN eval `ssh-agent -s` && \
printf "${SSH_KEY_PASSPHRASE}\n" | ssh-add $HOME/.ssh/id_rsa && \
yarn --pure-lockfile --mutex file --network-concurrency 1 && \
rm -rf /root/.ssh/
# Stage 2: build minified production code
FROM node:carbon AS production
WORKDIR /app/
COPY --from=sources /app/ /app/
COPY . /app/
RUN yarn build:prod
# Stage 3: include only built production files and host them with Node Express server
FROM node:carbon
WORKDIR /app/
RUN yarn add express
COPY --from=production /app/dist/ /app/dist/
COPY server.js /app/
EXPOSE 33330
CMD ["node", "server.js"]
.dockerignore.gitignoreफ़ाइल की सामग्री दोहराता है (यह परियोजना की निर्देशिकाओं को रोकता है node_modulesऔर जिसके परिणामस्वरूप distप्रतिलिपि बनाई जा रही है):
.idea
dist
node_modules
*.log
एक छवि बनाने के लिए कमांड उदाहरण:
$ docker build -t ezze/geoport:0.6.0 \
--build-arg SSH_KEY="$(cat ~/.ssh/id_rsa)" \
--build-arg SSH_KEY_PASSPHRASE="my_super_secret" \
./
यदि आपकी निजी SSH कुंजी में पासफ़्रेज़ नहीं है तो केवल खाली SSH_KEY_PASSPHRASEतर्क निर्दिष्ट करें ।
यह इस तरह काम करता है:
1)। केवल पहले चरण में package.json, yarn.lockफाइल और निजी SSH कुंजी को पहले इंटरमीडिएट इमेज नाम से कॉपी किया जाता है sources। आगे SSH कुंजी पासफ़्रेज़ से बचने के लिए यह स्वचालित रूप से जोड़ा जाता है ssh-agent। अंत में yarnकमांड एनपीएम से सभी आवश्यक निर्भरता स्थापित करता है और एसएसबी के ऊपर बिटबकैट से निजी गिट रिपॉजिटरी क्लोन करता है।
2)। दूसरा चरण वेब एप्लिकेशन के स्रोत कोड का निर्माण करता है और उसे distनामांकित करता है और इसे अगली इंटरमीडिएट इमेज नाम की निर्देशिका में रखता है production। ध्यान दें कि इंस्टॉल node_modulesकिए गए स्रोत कोड को sourcesइस लाइन द्वारा पहले चरण में निर्मित छवि से कॉपी किया गया है:
COPY --from=sources /app/ /app/
संभवतः यह निम्न पंक्ति भी हो सकती है:
COPY --from=sources /app/node_modules/ /app/node_modules/
हमारे node_modulesयहाँ पहले मध्यवर्ती छवि से केवल निर्देशिका है, कोई SSH_KEYऔर SSH_KEY_PASSPHRASEतर्क नहीं। बिल्ड के लिए आवश्यक सभी शेष हमारी परियोजना निर्देशिका से कॉपी किए गए हैं।
3)। तीसरे चरण में हम अंतिम छवि के एक आकार को कम करते हैं, जिसे वेब निर्देशिका शुरू करने के लिए नामांकित दूसरी इंटरमीडिएट छवि से ezze/geoport:0.6.0केवल distनिर्देशिका productionऔर नोड एक्सप्रेस स्थापित करके शामिल किया जाएगा ।
छवियों को सूचीबद्ध करना इस तरह एक आउटपुट देता है:
REPOSITORY TAG IMAGE ID CREATED SIZE
ezze/geoport 0.6.0 8e8809c4e996 3 hours ago 717MB
<none> <none> 1f6518644324 3 hours ago 1.1GB
<none> <none> fa00f1182917 4 hours ago 1.63GB
node carbon b87c2ad8344d 4 weeks ago 676MB
जहां गैर-टैग की गई छवियां पहले और दूसरे मध्यवर्ती बिल्ड चरणों के लिए संक्षिप्त हैं।
अगर तुम दौड़ते हो
$ docker history ezze/geoport:0.6.0 --no-trunc
आपको SSH_KEYऔर SSH_KEY_PASSPHRASEअंतिम छवि में कोई उल्लेख नहीं दिखाई देगा ।