एक छवि से डॉकरफाइल कैसे उत्पन्न करें?


241

क्या एक छवि से डॉकरफाइल उत्पन्न करना संभव है? मैं दो कारणों से जानना चाहता हूं:

  1. मैं रिपॉजिटरी से चित्र डाउनलोड कर सकता हूं, लेकिन उन्हें बनाने वाली रेसिपी देखना चाहूंगा।

  2. मुझे स्नैपशॉट को बचाने का विचार पसंद है, लेकिन एक बार जब मैं ऐसा कर लेता हूं तो यह समीक्षा करने के लिए एक संरचित प्रारूप होना अच्छा होगा।


आप Portainer.io portainer.io का उपयोग कर सकते हैं। यह एक वेब ऐप है जो आपके कंटेनरों के बारे में सभी (लगभग) सामान का प्रबंधन करने के लिए उपयोग किए जाने वाले डॉक कंटेनर के अंदर चलता है। यहां तक ​​कि छवियों की प्राप्ति।
विंसेंट

जवाबों:


98

एक छवि से डॉकरीफाइल कैसे उत्पन्न या रिवर्स किया जाए?

आप ऐसा कर सकते हैं।

alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage"
dfimage -sV=1.36 nginx:latest

यह लक्ष्य docker छवि को स्वचालित रूप से खींचेगा और निर्यात करेगा Dockerfile। पैरामीटर -sV=1.36की हमेशा आवश्यकता नहीं होती है।

संदर्भ: https://hub.docker.com/repository/docker/alpine/dfimage

नीचे पुराना उत्तर है, यह किसी भी अधिक काम नहीं करता है।

$ docker pull centurylink/dockerfile-from-image
$ alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm centurylink/dockerfile-from-image"
$ dfimage --help
Usage: dockerfile-from-image.rb [options] <image_id>
    -f, --full-tree                  Generate Dockerfile for all parent layers
    -h, --help                       Show this message

3
यह डॉकर तरीका है और इसे चुने गए उत्तर के रूप में चिह्नित किया जाना चाहिए।
kytwb

2
@ जेंसन यह सटीक नहीं है, 95% को कवर कर सकता है। लेकिन स्क्वैश छवि के साथ काम नहीं करता है।
बीएमडब्ल्यू

5
@ बीएमडब्ल्यू क्या आप अपने उदाहरण से छवि को चलाने में इस समस्या को हल करने में मदद कर सकते हैं? /us/ .sock (Errno :: ECONNREFUSED) (Excon :: त्रुटियां :: सॉकेटError)
लंबे समय तक

8
सेंचुरीलिंक / dockerfile-from-image नए संस्करण docker के साथ काम नहीं करता है। यह मेरे लिए एक काम करता है: hub.docker.com/r/chenzj/dfimage
aleung

6
इमेजेलिएर्स .io टूटा हुआ लगता है। यह अपने डेमो वाले सहित किसी भी छवि को नहीं पा सकता है
रॉबर्ट लैग

165

यह समझने के लिए कि डॉक छवि कैसे बनाई गई थी, docker history --no-truncकमांड का उपयोग करें ।

आप एक छवि से एक डॉक फ़ाइल बना सकते हैं, लेकिन इसमें वह सब कुछ नहीं होगा जो आप पूरी तरह से समझना चाहते हैं कि छवि कैसे उत्पन्न हुई थी। उचित रूप से आप जो निकाल सकते हैं वह मुख्य, ENV, EXPOSE, VOLUME, WORKDIR, ENTRYPOINT, CMD और डॉकफाइल के ONBUILD भाग हैं।

निम्नलिखित स्क्रिप्ट आपके लिए काम करना चाहिए:

#!/bin/bash
docker history --no-trunc "$1" | \
sed -n -e 's,.*/bin/sh -c #(nop) \(MAINTAINER .*[^ ]\) *0 B,\1,p' | \
head -1
docker inspect --format='{{range $e := .Config.Env}}
ENV {{$e}}
{{end}}{{range $e,$v := .Config.ExposedPorts}}
EXPOSE {{$e}}
{{end}}{{range $e,$v := .Config.Volumes}}
VOLUME {{$e}}
{{end}}{{with .Config.User}}USER {{.}}{{end}}
{{with .Config.WorkingDir}}WORKDIR {{.}}{{end}}
{{with .Config.Entrypoint}}ENTRYPOINT {{json .}}{{end}}
{{with .Config.Cmd}}CMD {{json .}}{{end}}
{{with .Config.OnBuild}}ONBUILD {{json .}}{{end}}' "$1"

मैं एक स्क्रिप्ट के भाग के रूप में इसका उपयोग चल रहे कंटेनरों को छवियों के रूप में पुनर्निर्माण करने के लिए करता हूं: https://github.com/docbill/docker-scripts/blob/master/docker-rebase

यदि आप एक छवि को फिर से तैयार करने में सक्षम होना चाहते हैं, तो डॉकरफाइल मुख्य रूप से उपयोगी है।

ध्यान रखने वाली बात, एक डॉकटर छवि वास्तव में केवल वास्तविक या आभासी मशीन का टार बैकअप हो सकता है। मैंने इस तरह से कई डॉकटर चित्र बनाए हैं। यहां तक ​​कि बिल्ड इतिहास मुझे छवि बनाने में पहला कदम के रूप में एक विशाल टार फ़ाइल आयात करने से पता चलता है ...


1
यह मुझे मिलता है: json: टाइप प्रकारों के मूल्य में असमान सरणी नहीं कर सकता। कोनेटनरसन
मोहसिन

क्या आप अपनी अंतिम टिप्पणी का अधिक विस्तार से वर्णन कर सकते हैं? क्या सब कुछ सामान्य है? या विशेष मामले हैं?
रॉबर्ट लुग

मुझे लगता है कि यह एक 6yo उत्तर है, लेकिन मुझे हो रहा हैError response from daemon: page not found
जोआ सियोका

53

मैं किसी भी तरह स्वीकार किए गए उत्तर में वास्तविक कमांड को पूरी तरह से याद करता हूं, इसलिए यहां फिर से, अपने पैराग्राफ में थोड़ा अधिक दिखाई देता है, यह देखने के लिए कि कितने लोग मेरे जैसे हैं

$ docker history --no-trunc <IMAGE_ID>

1
तो हमें आवश्यकता क्यों है ub.docker.com/r/chenzj/dfimage? इसका और भी हालिया जवाब है।
ल्यूसिड_ड्रीमर

3
मुझे लगता है क्योंकि docker historyडॉकरफ़ाइल लाइनों को एक रिवर्स ऑर्डर में प्रिंट करता है और यह RUNनिर्देशों को छोड़ देता है (आपको केवल कमांड ही मिलता है, RUNइसके सामने कीवर्कवर्क नहीं ) और अन्य सामान, इसलिए आपको इसे मैन्युअल रूप से एडिट करने के लिए एक बिल्डेबल गोकेरफाइल को प्राप्त करने की आवश्यकता है। वह अन्य उपकरण आपके लिए यह संपादन स्वचालित रूप से कर सकता है (मैंने इसकी कोशिश नहीं की थी, इसलिए मुझे नहीं पता।)
user7610

@ user7610 आपकी कमांड हब से खींची गई छवि का इतिहास दिखाती है। मैं अपने कमांड को डॉकटर छवियों पर कैसे देख सकता हूं?
बारजानहैती

@BarzanHayati क्या आप इसे एक नया प्रश्न पूछ सकते हैं और इसे यहाँ लिंक कर सकते हैं? पूछते समय बहुत विशिष्ट हो। छवि को शुरू करने के लिए कमांड दिखाएं, फिर कुछ आदेश जारी करें जिन्हें आप बाद में देखना चाहते हैं, उदाहरण के लिए, फिर कंटेनर को रोकें (यदि वास्तव में आप वास्तव में ऐसा करते हैं), और फिर पूछें कि जारी किए गए आदेशों को कैसे पुनः प्राप्त करें। धन्यवाद।
user7610

1
@ user7610 मैं इसे पूछ सकता था, लेकिन जैसे ही मैंने पूछा, मुझे इसे हटाना होगा क्योंकि अन्य उपयोगकर्ता मुझे बार-बार प्रश्न के लिए माइनस अंक देते हैं।
बारजानहैती

35

एक बैश समाधान:

docker history --no-trunc $argv  | tac | tr -s ' ' | cut -d " " -f 5- | sed 's,^/bin/sh -c #(nop) ,,g' | sed 's,^/bin/sh -c,RUN,g' | sed 's, && ,\n  & ,g' | sed 's,\s*[0-9]*[\.]*[0-9]*\s*[kMG]*B\s*$,,g' | head -n -1

कदम से कदम स्पष्टीकरण:

tac : reverse the file
tr -s ' '                                       trim multiple whitespaces into 1
cut -d " " -f 5-                                remove the first fields (until X months/years ago)
sed 's,^/bin/sh -c #(nop) ,,g'                  remove /bin/sh calls for ENV,LABEL...
sed 's,^/bin/sh -c,RUN,g'                       remove /bin/sh calls for RUN
sed 's, && ,\n  & ,g'                           pretty print multi command lines following Docker best practices
sed 's,\s*[0-9]*[\.]*[0-9]*\s*[kMG]*B\s*$,,g'      remove layer size information
head -n -1                                      remove last line ("SIZE COMMENT" in this case)

उदाहरण:

 ~  dih ubuntu:18.04
ADD file:28c0771e44ff530dba3f237024acc38e8ec9293d60f0e44c8c78536c12f13a0b in /
RUN set -xe
   &&  echo '#!/bin/sh' > /usr/sbin/policy-rc.d
   &&  echo 'exit 101' >> /usr/sbin/policy-rc.d
   &&  chmod +x /usr/sbin/policy-rc.d
   &&  dpkg-divert --local --rename --add /sbin/initctl
   &&  cp -a /usr/sbin/policy-rc.d /sbin/initctl
   &&  sed -i 's/^exit.*/exit 0/' /sbin/initctl
   &&  echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
   &&  echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean
   &&  echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean
   &&  echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean
   &&  echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages
   &&  echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes
   &&  echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests
RUN rm -rf /var/lib/apt/lists/*
RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
RUN mkdir -p /run/systemd
   &&  echo 'docker' > /run/systemd/container
CMD ["/bin/bash"]

1
सबसे सीधा उपाय है। धन्यवाद!
user3576508

जब यह मल्टीलाइन RUN स्टेटमेंट को तोड़ता है तो यह एक पीछे आने वाला बैकलैश नहीं जोड़ता है। मैंने इससे प्रेरित होकर अपना उत्तर जोड़ा है।
स्कॉट सेंटोनी

tac मैक पर उपलब्ध नहीं है, इसलिए आप नीचे की तरह awk के लिए जा सकते हैं: | awk '{प्रिंट एनआर, $ 0}' | सॉर्ट -nr | sed 's / ^ [0-9] * //' |
फुलेई

11

यह इस बिंदु पर संभव नहीं है (जब तक कि छवि के लेखक ने स्पष्ट रूप से डॉकरफाइल को शामिल नहीं किया है)।

हालांकि, यह निश्चित रूप से कुछ उपयोगी है! दो चीजें हैं जो इस सुविधा को प्राप्त करने में मदद करेंगी।

  1. ट्रस्टेड बिल्ड ( इस डोकर-देव चर्चा में विस्तृत)
  2. बिल्ड प्रक्रिया द्वारा निर्मित लगातार छवियों में अधिक विस्तृत मेटाडेटा। लंबे समय में, मेटाडेटा को इंगित करना चाहिए कि किस कमांड ने छवि का निर्माण किया, जिसका अर्थ है कि छवियों के अनुक्रम से डॉकरफाइल को फिर से बनाना संभव होगा।

8

अद्यतन दिसंबर 2018 बीएमडब्ल्यू के जवाब के लिए

docker pull chenzj/dfimage
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"
dfimage IMAGE_ID > Dockerfile

6

यह @ फॉलिनो के उत्तर से प्राप्त होता है, जिसमें कुछ समायोजन और सरलीकरण के साथ डॉक इतिहास के आउटपुट प्रारूप विकल्प का उपयोग किया जाता है । चूंकि macOS और Gnu / Linux में अलग-अलग कमांड-लाइन उपयोगिताओं हैं, मैक के लिए एक अलग संस्करण आवश्यक है। यदि आपको केवल एक या दूसरे की आवश्यकता है, तो आप बस उन पंक्तियों का उपयोग कर सकते हैं।

#!/bin/bash
case "$OSTYPE" in
    linux*)
        docker history --no-trunc --format "{{.CreatedBy}}" $1 | # extract information from layers
        tac                                                    | # reverse the file
        sed 's,^\(|3.*\)\?/bin/\(ba\)\?sh -c,RUN,'             | # change /bin/(ba)?sh calls to RUN
        sed 's,^RUN #(nop) *,,'                                | # remove RUN #(nop) calls for ENV,LABEL...
        sed 's,  *&&  *, \\\n \&\& ,g'                           # pretty print multi command lines following Docker best practices
    ;;
    darwin*)
        docker history --no-trunc --format "{{.CreatedBy}}" $1 | # extract information from layers
        tail -r                                                | # reverse the file
        sed -E 's,^(\|3.*)?/bin/(ba)?sh -c,RUN,'               | # change /bin/(ba)?sh calls to RUN
        sed 's,^RUN #(nop) *,,'                                | # remove RUN #(nop) calls for ENV,LABEL...
        sed $'s,  *&&  *, \\\ \\\n \&\& ,g'                      # pretty print multi command lines following Docker best practices
    ;;
    *)
        echo "unknown OSTYPE: $OSTYPE"
    ;;
esac

5

docker pull chenzj/dfimage


alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"

dfimage image_id

नीचे dfimage कमांड का ouput है: -

$ dfimage 0f1947a021ce

नोड से: 8 काम / usr / src / app

COPY फ़ाइल: e76d2e84545dedbe901b7b7b7b0c8d2c9733baa07cc821054efec48f623e29218c/ ./

RUN / बिन / sh -c npm स्थापित करें

COPY dir: a89a4894689a38cbf3895fdc0870878272bb9e09268149a87a6974a274b2184a

विस्तार 8080

CMD ["npm" "start"]

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