programing

이미지에서 도커 파일을 생성하는 방법은 무엇입니까?

lovejava 2023. 8. 7. 22:15

이미지에서 도커 파일을 생성하는 방법은 무엇입니까?

이미지에서 도커 파일을 생성할 수 있습니까?두 가지 이유로 알고 싶습니다.

  1. 저장소에서 이미지를 다운로드할 수 있지만 생성한 레시피를 보고 싶습니다.

  2. 스냅샷을 저장하는 것은 좋지만, 작업이 완료되면 작업 내용을 검토할 수 있는 체계적인 형식을 갖는 것이 좋습니다.

이미지에서 도커 파일을 생성하거나 되돌리는 방법은 무엇입니까?

넌 할 수 있다.주로.

참고: 다음을 생성하지 않습니다.Dockerfile직접 사용할 수 있는docker build출력은 단지 참조용입니다.

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

대상 도커 이미지를 자동으로 풀링하고 내보냅니다.Dockerfile매개 변수-sV=1.36반드시 필요한 것은 아닙니다.

참조: https://hub.docker.com/r/alpine/dfimage

이제 hub.docker.com 에서는 특정 태그를 선택하면 detail 명령을 사용하여 이미지 레이어를 직접 표시합니다.

enter image description here

보너스

각 계층에서 변경되는 파일을 알고 싶은 경우

alias dive="docker run -ti --rm  -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive"
dive nginx:latest

enter image description here

왼쪽에는 각 계층의 명령이 표시되고 오른쪽에는 노란색 선이 해당 계층에서 일부 파일이 변경되는 폴더가 표시됩니다.

(스페이스를 사용하여 dir 접기)

구답

아래는 오래된 대답입니다. 더 이상 작동하지 않습니다.

$ 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지휘권

이미지에서 도커 파일을 작성할 수는 있지만 이미지가 생성된 방식을 완전히 이해하기 위해 필요한 모든 내용이 포함되어 있지는 않습니다.합리적으로 추출할 수 있는 것은 도커 파일의 유지 관리자, ENV, 노출, 볼륨, WORKDIR, 엔트리 포인트, 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

도커 파일은 이미지를 다시 패키징할 수 있는 경우에 주로 유용합니다.

도커 이미지는 실제 또는 가상 시스템의 tar 백업일 수 있습니다.저는 이런 식으로 도커 이미지를 여러 개 만들었습니다.빌드 기록에서도 이미지를 만드는 첫 번째 단계로 큰 tar 파일을 가져오는 것으로 표시됩니다.

저는 어떻게든 승인된 답변에서 실제 명령을 완전히 놓쳤습니다. 그래서 여기에 다시 있습니다. 얼마나 많은 사람들이 저와 같은지 보기 위해 그 자체 단락에서 조금 더 잘 보입니다.

$ docker history --no-trunc <IMAGE_ID>

배시 솔루션:

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"]

BMW의 답변에 대한 2018년 12월 업데이트

chenzj/dfimage - hub.docker.com 에 설명된 대로 Docker 파일을 다른 이미지에서 재생성합니다.따라서 다음과 같이 사용할 수 있습니다.

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 허브 레지스트리에 있는 이미지에 관심이 있으며 Docker 파일을 살펴보려는 경우?

예:

이미지 "jupyter/data science-notebook"의 Docker 파일을 보려면 아래와 같이 브라우저의 주소 표시줄에 "Docker file"이라는 단어를 입력합니다.

https://hub.docker.com/r/jupyter/datascience-notebook/ enter image description here

https://hub.docker.com/r/jupyter/datascience-notebook/Dockerfile

enter image description here

참고: 일부 이미지에 도커 파일이 있는 것은 아닙니다(예: https://hub.docker.com/r/redislabs/redisinsight/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

이미지 작성자가 도커 파일을 명시적으로 포함하지 않는 한 이 시점에서는 불가능합니다.

하지만, 그것은 분명히 유용한 것입니다!이 기능을 얻는 데 도움이 되는 두 가지가 있습니다.

  1. 신뢰할 수 있는 빌드(이 도커 개발 논의에서 자세히 설명함)
  2. 빌드 프로세스에 의해 생성된 연속 이미지의 보다 자세한 메타데이터.장기적으로 메타데이터는 이미지를 생성한 빌드 명령을 나타내야 합니다. 즉, 일련의 이미지에서 도커 파일을 재구성할 수 있습니다.
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"]

그것은 단 두 단계로 가능합니다.먼저 이미지를 당긴 다음 도커 히스토리 명령을 실행합니다.SS에도 표시됩니다.

docker pull  kalilinux/kali-rolling
docker history --format "{{.CreatedBy}}"   kalilinux/kali-rolling --no-trunc

enter image description here

image2df란 무엇입니까?

image2df는 이미지별로 도커 파일 생성을 위한 도구입니다.

이 도구는 도커 이미지만 있고 도커 파일 화이트를 생성해야 할 경우 매우 유용합니다.

어떻게 작동합니까?

이미지의 기록 정보를 기준으로 역방향 구문 분석합니다.

이 이미지 사용 방법

# 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>
  • 도움말 보기

    docker run --rm cucker/image2df --help
    
  • 예를들면

    $ echo "alias image2df='docker run -v /var/run/docker.sock:/var/run/docker.sock --rm cucker/image2df'" >> ~/.bashrc
    $ . ~/.bashrc
    $ docker pull mysql
    $ image2df mysql
    
    ========== Dockerfile ==========
    FROM mysql:latest
    RUN groupadd -r mysql && useradd -r -g mysql mysql
    RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*
    ENV GOSU_VERSION=1.12
    RUN set -eux; \
        savedAptMark="$(apt-mark showmanual)"; \
        apt-get update; \
        apt-get install -y --no-install-recommends ca-certificates wget; \
        rm -rf /var/lib/apt/lists/*; \
        dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
        wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
        wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
        export GNUPGHOME="$(mktemp -d)"; \
        gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
        gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
        gpgconf --kill all; \
        rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
        apt-mark auto '.*' > /dev/null; \
        [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
        apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
        chmod +x /usr/local/bin/gosu; \
        gosu --version; \
        gosu nobody true
    RUN mkdir /docker-entrypoint-initdb.d
    RUN apt-get update && apt-get install -y --no-install-recommends \
            pwgen \
            openssl \
            perl \
            xz-utils \
        && rm -rf /var/lib/apt/lists/*
    RUN set -ex; \
        key='A4A9406876FCBD3C456770C88C718D3B5072E1F5'; \
        export GNUPGHOME="$(mktemp -d)"; \
        gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
        gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/mysql.gpg; \
        gpgconf --kill all; \
        rm -rf "$GNUPGHOME"; \
        apt-key list > /dev/null
    ENV MYSQL_MAJOR=8.0
    ENV MYSQL_VERSION=8.0.24-1debian10
    RUN echo 'deb http://repo.mysql.com/apt/debian/ buster mysql-8.0' > /etc/apt/sources.list.d/mysql.list
    RUN { \
            echo mysql-community-server mysql-community-server/data-dir select ''; \
        echo mysql-community-server mysql-community-server/root-pass password ''; \
        echo mysql-community-server mysql-community-server/re-root-pass password ''; \
        echo mysql-community-server mysql-community-server/remove-test-db select false; \
        } | debconf-set-selections \
        && apt-get update \
        && apt-get install -y \
            mysql-community-client="${MYSQL_VERSION}" \
            mysql-community-server-core="${MYSQL_VERSION}" \
        && rm -rf /var/lib/apt/lists/* \
        && rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
        && chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
        && chmod 1777 /var/run/mysqld /var/lib/mysql
    VOLUME [/var/lib/mysql]
    COPY dir:2e040acc386ebd23b8571951a51e6cb93647df091bc26159b8c757ef82b3fcda in /etc/mysql/
    COPY file:345a22fe55d3e6783a17075612415413487e7dba27fbf1000a67c7870364b739 in /usr/local/bin/
    RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
    ENTRYPOINT ["docker-entrypoint.sh"]
    EXPOSE 3306 33060
    CMD ["mysqld"]
    
  • 언급

언급URL : https://stackoverflow.com/questions/19104847/how-to-generate-a-dockerfile-from-an-image