Docker:通过容器生成镜像的三种方法

时间:2025-03-20 17:29:27

Docker中有时需要修改别人制作好的镜像,一般的方法就是通过创建镜像的容器,将容器进行修改,之后通过容器创建新的镜像。本文主要介绍Docker 将容器生成镜像的三种方法。

1、使用docker commit创建镜像(推荐)

  1. 查看容器ID docker ps -a
  2. 通过容器ID创建镜像

2、使用docker export和docker import创建镜像

  1. 查看容器ID docker ps -a
  2. 导出容器到文件 docker export >
  3. 加载保存的容器创建镜像 docker import :[TAG]

**注意:**使用此方法也可以将容器进行压缩,另外这样创建的容器可能不能正常启动,我们还需要指定一下启动需要参数,例如,entrypoint、cmd和环境变量等。

3、使用tar导出容器创建镜像

  1. 进入容器 sudo docker exec -it /bin/bash
  2. 生成镜像文件 tar -cvf --exclude=/proc --exclude=/sys --exclude= /
  3. 将容器中生成的文件拷贝到宿主机 sudo docker cp :/ .
  4. 创建生成镜像 cat | sudo docker import - :[TAG]

**注意:**使用此方法也可以将容器进行压缩,另外这样创建的容器可能不能正常启动,我们还需要指定一下启动需要参数,例如,entrypoint、cmd和环境变量等。

4、查看镜像的Dockerfile的方法

  1. 使用docker history查看信息通过docker history查看镜像信息来分析生成Dockerfile。但少了FROM指令信息,多出来自BASIC_IMAGE的一些指令信息。
  2. 使用DockerImage2Df容器工具
docker commit -m "oracle 11g" d038360bc3b8 cjavapy/oracle11g:latest

docker commit用法:docker commit  参数  容器名或容器id  镜像名。
参数说明:
-a:提交的镜像作者;
-c:使用Dockerfile指令来创建镜像;
-m:提交时的说明文字;
-p:在commit时,将容器暂停。(默认选项)
#!/bin/bash
set -u

USAGE_TIPS="Usage: ./ <IMAGE>"

if [ !$1 ];
   echo ${USAGE_TIPS}
   exit 1
fi

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

将上面内容存为,使用方法如下,

dfimage hanxiao/mynginx:4.1
# 命令alias
echo "alias image2df='docker run -v /var/run/:/var/run/ --rm cucker/image2df'" >> ~/.bashrc
. ~/.bashrc
# 使用方法
image2df <IMAGE

项目地址**:**/cucker0/dockerimage2df

$ echo "alias image2df='docker run -v /var/run/:/var/run/ --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 "/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
    wget -O /usr/local/bin/ "/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$"; \
    export GNUPGHOME="$(mktemp -d)"; \
    gpg --batch --keyserver hkps:// --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
    gpg --batch --verify /usr/local/bin/ /usr/local/bin/gosu; \
    gpgconf --kill all; \
    rm -rf "$GNUPGHOME" /usr/local/bin/; \
    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 /
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  --recv-keys "$key"; \
    gpg --batch --export "$key" > /etc/apt//; \
    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 /apt/debian/ buster mysql-8.0' > /etc/apt//
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/ / # backwards compat
ENTRYPOINT [""]
EXPOSE 3306 33060
CMD ["mysqld"]