เป็นไปได้หรือไม่ที่จะสร้าง Dockerfile จากภาพ? ฉันต้องการทราบด้วยสองเหตุผล:
ฉันสามารถดาวน์โหลดภาพจากพื้นที่เก็บข้อมูล แต่ต้องการดูสูตรที่สร้าง
ฉันชอบความคิดในการบันทึกสแนปชอต แต่เมื่อฉันทำมันจะเป็นการดีที่มีรูปแบบที่มีโครงสร้างเพื่อตรวจสอบสิ่งที่ทำ
เป็นไปได้หรือไม่ที่จะสร้าง Dockerfile จากภาพ? ฉันต้องการทราบด้วยสองเหตุผล:
ฉันสามารถดาวน์โหลดภาพจากพื้นที่เก็บข้อมูล แต่ต้องการดูสูตรที่สร้าง
ฉันชอบความคิดในการบันทึกสแนปชอต แต่เมื่อฉันทำมันจะเป็นการดีที่มีรูปแบบที่มีโครงสร้างเพื่อตรวจสอบสิ่งที่ทำ
คำตอบ:
จะสร้างหรือย้อนกลับ Dockerfile จากภาพได้อย่างไร?
คุณสามารถ.
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage"
dfimage -sV=1.36 nginx:latest
มันจะดึง automaticlaly 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
เพื่อให้เข้าใจถึงการสร้างอิมเมจของนักเทียบท่าใช้
docker history --no-trunc
คำสั่ง
คุณสามารถสร้างไฟล์นักเทียบท่าจากภาพ แต่มันจะไม่มีทุกสิ่งที่คุณต้องการที่จะเข้าใจอย่างสมบูรณ์ว่าภาพนั้นถูกสร้างขึ้นอย่างไร สิ่งที่คุณสามารถแยกได้คือ MAINTAINER, ENV, EXPOSE, VOLUME, WORKDIR, ENTRYPOINT, CMD และ ONBUILD บางส่วนของ dockerfile
สคริปต์ต่อไปนี้ควรใช้กับคุณ:
#!/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
Dockerfile มีประโยชน์ส่วนใหญ่หากคุณต้องการที่จะสามารถบรรจุภาพ
สิ่งที่ควรคำนึงถึงคืออิมเมจนักเทียบท่านั้นสามารถสำรองทาร์ของเครื่องจริงหรือเสมือนได้ ฉันทำภาพนักเทียบท่าหลายรูปด้วยวิธีนี้ แม้แต่ประวัติการสร้างแสดงให้ฉันเห็นการนำเข้าไฟล์ tar ขนาดใหญ่เป็นขั้นตอนแรกในการสร้างภาพ ...
Error response from daemon: page not found
ฉันพลาดคำสั่งจริงในคำตอบที่ยอมรับดังนั้นฉันก็เลยเห็นอีกครั้งในย่อหน้าของมันเองเพื่อดูว่ามีคนมากมายแค่ไหนในตัวฉัน
$ docker history --no-trunc <IMAGE_ID>
ub.docker.com/r/chenzj/dfimage
? มันเป็นคำตอบที่ใหม่กว่า
docker history
พิมพ์บรรทัด Dockerfile ในลำดับย้อนกลับและมันลดRUN
คำแนะนำ (คุณได้รับเพียงคำสั่งเองไม่ใช่RUN
keyworkd อยู่ข้างหน้า) และสิ่งอื่น ๆ ดังนั้นคุณต้องแก้ไขด้วยตนเองเพื่อไปที่ Dockerfile ที่ buildable ได้ เครื่องมืออื่นอาจทำการแก้ไขนี้โดยอัตโนมัติสำหรับคุณ (ฉันไม่ได้ลองดังนั้นฉันไม่รู้)
วิธีทุบตี:
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"]
ไม่สามารถทำได้ในตอนนี้ (เว้นแต่ว่าผู้แต่งรูปภาพจะรวม Dockerfile ไว้อย่างชัดเจน)
อย่างไรก็ตามมันมีประโยชน์อย่างแน่นอน! มีสองสิ่งที่จะช่วยให้ได้รับคุณลักษณะนี้
อัปเดตธันวาคม 2561 เป็นคำตอบของ BMW
docker pull chenzj/dfimage
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"
dfimage IMAGE_ID > Dockerfile
นี้ได้มาจากคำตอบของ @ fallino มีการปรับและ simplifications โดยใช้ตัวเลือกรูปแบบการออกสำหรับประวัตินักเทียบท่า เนื่องจาก 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
docker pull chenzj/dfimage
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"
dfimage image_id
ด้านล่างคือ ouput ของคำสั่ง dfimage: -
$ dfimage 0f1947a021ce
จากโหนด: 8 WORKDIR / usr / src / app
ไฟล์สำเนา: e76d2e84545dedbe901b7b7b0c8d2c9733baa07cc821054efec48f623e29218c ใน. /
ติดตั้ง RUN / bin / sh -c npm
สำเนา COPY: a89a4894689a38cbf3895fdc0870878272bb9e09268149a87a69a6974a6974a6974a274b2184a ใน
เปิดเผย 8080
CMD ["npm" "start"]