Как сгенерировать Dockerfile из изображения?
Можно ли сгенерировать Dockerfile из изображения? Я хочу знать по двум причинам:
Я могу загрузить изображения из хранилища, но хотел бы увидеть рецепт, который их сгенерировал.
Мне нравится идея сохранения снимков, но как только я это сделаю, было бы неплохо иметь структурированный формат для просмотра того, что было сделано.
12 ответов
Чтобы понять, как был создан образ докера, используйтеdocker history --no-trunc
команда.
Вы можете создать файл Docker из изображения, но он не будет содержать всего, что вы хотели бы полностью понять, как было сгенерировано изображение. Разумно то, что вы можете извлечь, это части Dockerfile: MAINTAINER, 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
Dockerfile в основном полезен, если вы хотите иметь возможность перепаковать изображение.
Следует помнить, что образ докера может быть просто резервной копией реального или виртуального компьютера. Таким образом, я сделал несколько снимков докеров. Даже история сборки показывает, что я импортировал огромный tar-файл как первый шаг в создании образа...
Обновить:
Цитата из комментария @aleung:
centurylink/dockerfile-from-image
не работает с новой версией докера. Этот работает для меня: hub.docker.com/r/chenzj/dfimage
Как сгенерировать Dockerfile из изображения?
Вы можете.
Первый путь
$ 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
Вот пример для генерации Dockerfile из существующего образа selenium/node-firefox-debug
core@core-01 ~ $ docker pull centurylink/dockerfile-from-image
core@core-01 ~ $ alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm centurylink/dockerfile-from-image"
core@core-01 ~ $ dfimage selenium/node-firefox-debug
ADD file:b43bf069650bac07b66289f35bfdaf474b6b45cac843230a69391a3ee342a273 in /
RUN 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
RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
CMD ["/bin/bash"]
MAINTAINER Selenium <selenium-developers@googlegroups.com>
RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main universe\n" > /etc/apt/sources.list && echo "deb http://archive.ubuntu.com/ubuntu trusty-updates main universe\n" >> /etc/apt/sources.list
RUN apt-get update -qqy && apt-get -qqy --no-install-recommends install ca-certificates openjdk-7-jre-headless unzip wget && rm -rf /var/lib/apt/lists/* && sed -i 's/\/dev\/urandom/\/dev\/.\/urandom/' ./usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/java.security
RUN mkdir -p /opt/selenium && wget --no-verbose http://selenium-release.storage.googleapis.com/2.46/selenium-server-standalone-2.46.0.jar -O /opt/selenium/selenium-server-standalone.jar
RUN sudo useradd seluser --shell /bin/bash --create-home && sudo usermod -a -G sudo seluser && echo 'ALL ALL = (ALL) NOPASSWD: ALL' >> /etc/sudoers && echo 'seluser:secret' | chpasswd
MAINTAINER Selenium <selenium-developers@googlegroups.com>
ENV DEBIAN_FRONTEND=noninteractive
ENV DEBCONF_NONINTERACTIVE_SEEN=true
ENV TZ=US/Pacific
RUN echo "US/Pacific" | sudo tee /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata
RUN apt-get update -qqy && apt-get -qqy install xvfb && rm -rf /var/lib/apt/lists/*
COPY file:335d2f6f9bfe311d2b38034ceab3b2ae2a1e07b9b203b330cac9857d6e17c148 in /opt/bin/entry_point.sh
RUN chmod +x /opt/bin/entry_point.sh
ENV SCREEN_WIDTH=1360
ENV SCREEN_HEIGHT=1020
ENV SCREEN_DEPTH=24
ENV DISPLAY=:99.0
USER [seluser]
CMD ["/opt/bin/entry_point.sh"]
MAINTAINER Selenium <selenium-developers@googlegroups.com>
USER [root]
RUN apt-get update -qqy && apt-get -qqy --no-install-recommends install firefox && rm -rf /var/lib/apt/lists/*
COPY file:52a2a815e3bb6b85c5adfbceaabb5665b63f63ef0fb0e3f774624ee399415f84 in /opt/selenium/config.json
USER [seluser]
MAINTAINER Selenium <selenium-developers@googlegroups.com>
USER [root]
RUN apt-get update -qqy && apt-get -qqy install x11vnc && rm -rf /var/lib/apt/lists/* && mkdir -p ~/.vnc && x11vnc -storepasswd secret ~/.vnc/passwd
ENV LANGUAGE=en_US.UTF-8
ENV LANG=en_US.UTF-8
RUN locale-gen en_US.UTF-8 && dpkg-reconfigure --frontend noninteractive locales && apt-get update -qqy && apt-get -qqy --no-install-recommends install language-pack-en && rm -rf /var/lib/apt/lists/*
RUN apt-get update -qqy && apt-get -qqy --no-install-recommends install fonts-ipafont-gothic xfonts-100dpi xfonts-75dpi xfonts-cyrillic xfonts-scalable && rm -rf /var/lib/apt/lists/*
RUN apt-get update -qqy && apt-get -qqy install fluxbox && rm -rf /var/lib/apt/lists/*
COPY file:90e3a7f757c3df44d541b59234ad4ca996f799455eb8d426218619b244ebba68 in /opt/bin/entry_point.sh
RUN chmod +x /opt/bin/entry_point.sh
EXPOSE 5900/tcp
Другой способ, при котором вам не нужно тянуть образ в локальный режим и не нужно запускать команды.
Используйте приведенное выше изображение в качестве примера, вы можете получить команды Dockerfile через следующий URL:
https://imagelayers.io/?images=selenium%2Fnode-firefox-debug:latest
Подождите некоторое время, появятся два окна, в верхнем окне перечислены слои, в нижнем - команда в Dockerfile.
Формат URL:
https://imagelayers.io/?images=<USER>%2F<IMAGE>:<TAG>
В лице imagelayers.io построен Centurylink
Я почему-то абсолютно пропустил фактическую команду в принятом ответе, поэтому здесь она снова, немного более заметна в своем собственном абзаце, чтобы увидеть, сколько людей похоже на меня
$ docker history --no-trunc <IMAGE_ID>
Решение Bash:
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]*[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]*[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"]
Обновите декабрь 2018 года до ответа 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
Если вас интересует образ, который находится в реестре Docker Hub, и вы хотите взглянуть на Dockerfile?.
Пример:
Если вы хотите увидеть Dockerfile изображения «jupyter/datascience-notebook», введите слово «Dockerfile» в адресной строке браузера, как показано ниже.
https://hub.docker.com/r/jupyter/datascience-ноутбук/
https://hub.docker.com/r/jupyter/datascience-notebook/Dockerfile
Примечание. Не все образы имеют Dockerfile, например, https://hub.docker.com/r/redislabs/redisinsight/Dockerfile Иногда этот способ намного быстрее, чем поиск Dockerfile в Github.
Это вытекает из ответа @fallino, с некоторыми корректировками и упрощениями при использовании опции формата вывода для истории докера. Поскольку macOS и Gnu/Linux имеют разные утилиты командной строки, для Mac необходима другая версия
#!/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
На данный момент это невозможно (если автор изображения явно не включил Dockerfile).
Тем не менее, это определенно что-то полезное! Есть две вещи, которые помогут получить эту функцию.
- Надежные сборки (подробно в этом обсуждении docker-dev
- Более подробные метаданные в последовательных изображениях, полученных в процессе сборки. В конечном счете, метаданные должны указывать, какая команда построения создала образ, а это значит, что будет возможно восстановить Dockerfile из последовательности изображений.
docker pull chenzj/dfimage
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"
dfimage image_id
Ниже приведен вывод команды dfimage:
$ dfimage 0f1947a021ce
FROM node:8
WORKDIR /usr/src/app
COPY file:e76d2e84545dedbe901b7b7b0c8d2c9733baa07cc821054efec48f623e29218c in ./
RUN /bin/sh -c npm install
COPY dir:a89a4894689a38cbf3895fdc0870878272bb9e09268149a87a6974a274b2184a in .
EXPOSE 8080
CMD ["npm" "start"]
это возможно всего за два шага. Сначала извлеките образ, затем запустите команду истории докеров. также, показано в СС.
docker pull kalilinux/kali-rolling
docker history --format "{{.CreatedBy}}" kalilinux/kali-rolling --no-trunc
Вы можете использовать Portainer.io https://portainer.io/
Это веб-приложение, которое запускается в док-контейнере, используемом для управления всеми (почти) материалами о ваших контейнерах. Даже изображения получаются.
DockerImage2Df
Что такое DockerImage2Df
DockerImage2Df - это инструмент для создания файла Dockerfile из изображения.
Этот инструмент очень полезен, когда у вас есть только образ докера и вам нужно сгенерировать Dockerfile с ним.
Как использовать это изображение
# Command alias
echo "alias image2df='docker run -v /var/run/docker.sock:/var/run/docker.sock --rm cucker/image2df'" >> ~/.bashrc
. ~/.bashrc
# Excute command
image2df <IMAGE>