案例:Docker 镜像的创建及使用(commit与dockerfile方式)

这篇具有很好参考价值的文章主要介绍了案例:Docker 镜像的创建及使用(commit与dockerfile方式)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、commit方式创建镜像

我要将一个包含nginx的容器做成一个镜像,供其他人使用,这样其他人就不必再执行nginx安装等操作。

1.1、前期准备

首先,还是启动一个容器:

docker run -it --name n1 centos /bin/bash

命名为n1。

然后在容器内部安装nginx:

yum install nginx -y

这里yum源出现问题:
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
解决看这里

安装成功并启动运行:

whereis nginx

/usr/sbin/nginx

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器

在另一个终端,查看nginx情况:

docker inspect n1  # n1是该容器的name
[
    {
        "Id": "704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9",
        "Created": "2023-08-06T12:27:49.98892154Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 16981,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2023-08-06T12:27:50.31650392Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "ResolvConfPath": "/var/lib/docker/containers/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9/hostname",
        "HostsPath": "/var/lib/docker/containers/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9/hosts",
        "LogPath": "/var/lib/docker/containers/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9-json.log",
        "Name": "/n1",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "ConsoleSize": [
                50,
                180
            ],
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": [],
            "BlkioDeviceWriteBps": [],
            "BlkioDeviceReadIOps": [],
            "BlkioDeviceWriteIOps": [],
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/e256f9203c6a18429e19e0d9458494cf25de028eeb086697f77f6f12bb2bb82e-init/diff:/var/lib/docker/overlay2/0351cac31df5ec6bd716f7dd314842417100097dcad45cdbf3b2b602df85ac0d/diff",
                "MergedDir": "/var/lib/docker/overlay2/e256f9203c6a18429e19e0d9458494cf25de028eeb086697f77f6f12bb2bb82e/merged",
                "UpperDir": "/var/lib/docker/overlay2/e256f9203c6a18429e19e0d9458494cf25de028eeb086697f77f6f12bb2bb82e/diff",
                "WorkDir": "/var/lib/docker/overlay2/e256f9203c6a18429e19e0d9458494cf25de028eeb086697f77f6f12bb2bb82e/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "704c3c99bc66",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20210915",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "7ff17da73c9e66bbfbd41b199708eda43a0755d1e2719ef4e07234f4d241e385",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/7ff17da73c9e",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "3674d5008409dc73853dc14b6c7627ab5d5bcaf2786df5f12c43a966613256e6",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "348aaaac8b83d35b8f2b750e66eefa696566a774d5791710e2b15e0e3d101332",
                    "EndpointID": "3674d5008409dc73853dc14b6c7627ab5d5bcaf2786df5f12c43a966613256e6",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

然后看到 ip是 172.17.0.2,访问nginx指令:

curl  172.17.0.2

访问成功!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <title>Test Page for the Nginx HTTP Server on Red Hat Enterprise Linux</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <style type="text/css">
            /*<![CDATA[*/
            body {
                background-color: #fff;
                color: #000;
                font-size: 0.9em;
                font-family: sans-serif,helvetica;
                margin: 0;
                padding: 0;
            }
            :link {
                color: #c00;
            }
            :visited {
                color: #c00;
            }
            a:hover {
                color: #f50;
            }
            h1 {
                text-align: center;
                margin: 0;
                padding: 0.6em 2em 0.4em;
                background-color: #900;
                color: #fff;
                font-weight: normal;
                font-size: 1.75em;
                border-bottom: 2px solid #000;
            }
            h1 strong {
                font-weight: bold;
                font-size: 1.5em;
            }
            h2 {
                text-align: center;
                background-color: #900;
                font-size: 1.1em;
                font-weight: bold;
                color: #fff;
                margin: 0;
                padding: 0.5em;
                border-bottom: 2px solid #000;
            }
            hr {
                display: none;
            }
            .content {
                padding: 1em 5em;
            }
            .alert {
                border: 2px solid #000;
            }

            img {
                border: 2px solid #fff;
                padding: 2px;
                margin: 2px;
            }
            a:hover img {
                border: 2px solid #294172;
            }
            .logos {
                margin: 1em;
                text-align: center;
            }
            /*]]>*/
        </style>
    </head>

    <body>
        <h1>Welcome to <strong>nginx</strong> on Red Hat Enterprise Linux!</h1>

        <div class="content">
            <p>This page is used to test the proper operation of the
            <strong>nginx</strong> HTTP server after it has been
            installed. If you can read this page, it means that the
            web server installed at this site is working
            properly.</p>

            <div class="alert">
                <h2>Website Administrator</h2>
                <div class="content">
                    <p>This is the default <tt>index.html</tt> page that
                    is distributed with <strong>nginx</strong> on
                    Red Hat Enterprise Linux.  It is located in
                    <tt>/usr/share/nginx/html</tt>.</p>

                    <p>You should now put your content in a location of
                    your choice and edit the <tt>root</tt> configuration
                    directive in the <strong>nginx</strong>
                    configuration file
                    <tt>/etc/nginx/nginx.conf</tt>.</p>

                    <p>For information on Red Hat Enterprise Linux, please visit the <a href="http://www.redhat.com/">Red Hat, Inc. website</a>. The documentation for Red Hat Enterprise Linux is <a href="http://www.redhat.com/docs/manuals/enterprise/">available on the Red Hat, Inc. website</a>.</p>

                </div>
            </div>

            <div class="logos">
                <a href="http://nginx.net/"><img
                    src="nginx-logo.png" 
                    alt="[ Powered by nginx ]"
                    width="121" height="32" /></a>
                <a href="http://www.redhat.com/"><img
                    src="poweredby.png"
                    alt="[ Powered by Red Hat Enterprise Linux ]"
                    width="88" height="31" /></a>
            </div>
        </div>
    </body>
</html>

1.2、制成镜像

将刚才的bash退回到宿主机:
注意!如果使用exit指令,退出容器时容器包括内部的镜像都停止了,我们要后台运行退出,使用如下指令:

Ctrl+P+Q

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
然后制作镜像:
docker commit 容器名 自定义镜像名

docker commit n1 cent-nginx:v1

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
提交成功,查看一下镜像列表:

docker images

可以看到我们制作好的镜像~
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器

1.3、启动镜像

1.3.1、启动镜像+启动nginx

docker run -it --name nginx1 cent-nginx:v1 /bin/bash

然后在nginx1容器里查看,nginx此时是没有启动的:
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器

在外部,查看容器启动情况:

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
可以看到nginx1确实在运行中。

那么想要运行nginx,则还是手动启动:
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
然后另一边再访问nginx,访问成功~

docker inspect nginx1  # 查看ip

curl 172.17.0.3

启动容器还得再进入内部启动nginx,很麻烦~

1.3.2、一个命令直接全部启动

docker run -d --name nginx2 cent-nginx:v1 /usr/sbin/nginx -g "daemon off;"

解释: 这里指定了nginx要做的事情
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器

1.3.3、两种方式区别

1、nginx 启动服务: /usr/sbin/nginx (不会结束一直前台跑)
2、/usr/sbin/nginx -g “daemon off;”

后面运行的命令都是容器命令,由于nginx命令没有设置到path中,所以全路径启动,
而nginx -g这个参数是指可以在外面添加指令到nginx的配置文件中,
daemon off是指nginx服务不运行在后端,而是在前台运行(container中的服务必须运行在前台)

1.4、commit创建镜像方式的本质

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
原容器与commit后的镜像,在文件系统上并无区别。只是把容器层原来的可写属性,置成了只读。于是变成了一个不可改的镜像。

2、Dockerfile的使用

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器

2.1、Dockerfile指令

先看这个表格:

关键字 作用 备注
FROM 指定父镜像 指定dockerfile基于那个image构建
MAINTAINER 作者信息 用来标明这个dockerfile谁写的
LABEL 标签 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN 执行命令 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”]
CMD 容器启动命令 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”]
ENTRYPOINT 入口 一般在制作一些执行就关闭的容器中会使用
COPY 复制文件 build的时候复制文件到image中
ADD 添加文件 build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
ENV 环境变量 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG 构建参数 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME 定义外部可以挂载的数据卷 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”]
EXPOSE 暴露端口 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR 工作目录 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER 指定执行用户 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK 健康检查 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD 触发器 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL 发送信号量到宿主机 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL 指定执行脚本的shell 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

以下是重点指令的解读~

  • FROM
      FROM {base镜像}
      必须放在DOckerfile的第一行,表示从哪个baseimage开始构建
  • MAINTAINER
    可选的,用来标识image作者的地方
  • RUN
    RUN都是启动一个容器、执行命令、然后提交存储层文件变更。
    第一层 RUN command1 的执行仅仅是当前进程,一个内存上的变化而已,其结果不会造成任何文件。
    而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。
    而如果需要将两条命令或者多条命令联合起来执行需要加上&&。
    如:cd /usr/local/src && wget xxxxxxx
  • CMD
      CMD的作用是作为执行container时候的默认行为(容器默认的启动命令)
      当运行container的时候声明了command,则不再用image中的CMD默认所定义的命令
    一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用
  • EXPOSE
    EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
  • entrypoint
    entrypoint的作用是,把整个container变成可执行的文件,且不能够通过替换CMD的方法来改变创建container的方式。但是可以通过参数传递的方法影响到container内部
    每个Dockerfile只能够包含一个entrypoint,多个entrypoint只有最后一个有效
    当定义了entrypoint以后,CMD只能够作为参数进行传递
  • ADD & COPY
      把host上的文件或者目录复制到image中(能够进行自动解压压缩包)
  • ENV
      用来设置环境变量,后续的RUN可以使用它所创建的环境变量
  • WORKDIR
      用来指定当前工作目录(或者称为当前目录)
  • USER
      运行RUN指令的用户
  • VOLUME
      用来创建一个在image之外的mount point

2.2、nginx镜像制作案例

首先,创建一个新目录,在该目录下制作:

mkdir dockerfile-nginx
cd dockerfile-nginx

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
然后创建并编辑Dockerfile文件:

vi Dcokerfile

文件内容如下:

# Base image
FROM centos:7

# MAINTAINER
MAINTAINER cyl

# 将nginx以及pcre源代码加入镜像
ADD nginx-1.20.1.tar.gz /usr/local/src/
ADD pcre-8.45.tar.gz /usr/local/src/

# 安装编译器
RUN yum install -y gcc gcc-c++ make openssl-devel lsof
RUN useradd -s /sbin/nologin -M nginx

# 指定工作目录
WORKDIR /usr/local/src/nginx-1.20.1/

# 编译nginx
RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.45 && make && make install
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf

# 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH

# 暴露80端口
EXPOSE 80

# 容器默认启动命令
ENTRYPOINT ["nginx"]

然后保存退出,wget下载这两个源码包:

wget http://nginx.org/download/nginx-1.13.2.tar.gz
wget http://downloads.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.gz

然后开始build构建:

docker build -t cent-ngx2 .   # . 表示在当前目录下构建

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
这里奇怪的是,我构建完毕,没有出现successfully的提示(但是nginx依然构建成功可以正常运行):
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器

然后,run运行并指定端口映射:

docker run -d --name ngx2 -p 80:80 cent-ngx2

运行成功,浏览器访问(linux宿主机ip+端口80):
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器

2.3、查看构建历史:

docker history 镜像id

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
此镜像层基本与dockerfile文件的RUN是一一对应的。
注:missing表示无法获取image id,通常从docker hub下载的镜像会有这个问题

以上dockerfile中指定了启动命令(前台启动),假如未指定,构建成功后,又想要制定怎么办?

为镜像指定环境变量,挂载目录,默认启动命令

在上一版镜像的基础上,新加配置:
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
执行:

docker build -t cent-ngx3

查看镜像的历史,可看到比ngx2的镜像多了几个层。
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
镜像的缓存特性

docker会缓存已有的镜像层,构建镜像时,如果某镜像层已经存在,就直接使用,无需创建,如果不希望在构建镜像时使用缓存,可以在docker build命令中加上–no-cache参数。dockerfile中每一个指令都会创建一个镜像层,上层依赖于下层的。无论什么时候,只要某一层发生变化,其上面所有层的缓存都会失效。除了构建时使用缓存,docker在下载镜像时也会使用

调试dockerfile

在执行dockerfile时,如果因为某种原因执行到某个指令失败了,也能够得到前一个指令成功执行构建出的容器,可以运行新的镜像,手动运行那条失败的指令,从而定位失败的原因

2.4、run VS cmd VS entrypoint

  • RUN:执行命令并创建新的镜像层,常用于安装软件包;
  • CMD:设置容器启动后默认执行的命令及其参数,但 docker run 后跟参数时会替换(忽略) CMD
  • ENTRYPOINT:配置容器启动时运行的命令。

案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器

docker容器的主业

docker理念里,容器启动时,应当为它指定主业是什么,如nginx容器主业就是nginx代理服务,tomcat容器就是web服务等等
1、容器创建时,必须指定主业任务,如不指定,则容器无事可干立即退出。
2、在dockerfile打包镜像时,可以使用cmd命令来指定一个默认的主业,如下:
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
3、既然镜像里是默认主业,即意味着创建容器时,可以覆盖此默认命令,如下
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器

推荐的ENTRYPOINT 方式

1、镜像本身应该有稳定的主业,应当指定后即不能更改用途,于是引入ENTRYPOINT
2、使用ENTRYPOINT字义即容器入口,它不能被run中cmd覆盖,如下例:
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
执行:docker build -t nginxx:v3 .
案例:Docker 镜像的创建及使用(commit与dockerfile方式),docker,容器
以后使用nginxx:v3这个镜像时,只能做nginx服务来使用。

更详细用法看这里

3、commit和Dockerfile的区别

Commit生成的镜像和Dockerfile有以下几点区别:

  1. Commit生成的镜像是一个完整的镜像,而Dockerfile只是一个构建镜像的指令文件,它只能用于构建镜像,而不能用于运行容器。
  2. Commit生成的镜像可以直接运行容器,而Dockerfile只能用于构建镜像,不能直接运行容器。
  3. Commit生成的镜像可以直接推送到远程仓库,而Dockerfile不能直接推送到远程仓库,必须先构建镜像,然后再推送到远程仓库。

Docker commit的缺点如下:

  1. 需要在容器内操作麻烦,效率低。
  2. 这一点也是最重要的,使用docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑箱镜像。其他人或者过一段时间后自己也不知道这个镜像是怎么做出来的,都安装了什么。但是使用Dockerfile构建的镜像,我们可以通过构建历史查看每一层做了什么。
  3. 而且,commit任何修改的结果仅仅是在当前层进行标记,添加,修改,而不会改动上一层。如果使用docker commit制作镜像,以及后期修改的话,每一次修改都会让镜像更加臃肿一次,所删除的上一层的东西并不会丢失,会一直如影随形的跟着这个镜像,即使根本无法访问到,这会使镜像更加臃肿。

那么为什么还要学习这种方式?文章来源地址https://www.toymoban.com/news/detail-632087.html

  1. docker commit有一些特殊的应用场合,比如被入侵后保存现场等。但是,不要使用docker commmit定制镜像,定制行为应该使用Dockerfile来完成
  2. Dockerfille每一步build出来的镜像正是通过docker commit 构建出来的。学习commit可以有助于我们理解dockerfile。

到了这里,关于案例:Docker 镜像的创建及使用(commit与dockerfile方式)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Docker:使用dockerFile创建镜像(war包和jar包)

    1、使用war包打镜像 (1)在war的当前路径下,新建一个文件——Dockerfile (2)编辑Dockerfile文件    vim Dockerfile Dockerfile文件内容: FROM java:8                # 选择项目中要求的版本 MAINTAINER ylb             # 作者 WORKDIR /穿件文件夹的路径    # 选择项目中要求的

    2024年02月15日
    浏览(45)
  • 【Docker】初识 Docker,Docker 基本命令的使用,Dockerfile 自定义镜像的创建

    在部署大型项目时,常常面临多组件、复杂的依赖关系和不同环境之间的差异,这些因素可能导致以下问题: 复杂的依赖关系: 由于项目组件众多,各个组件之间的依赖关系变得复杂,容易出现版本不匹配或兼容性问题。 兼容性问题: 项目在不同的环境中可能会遇到兼容性

    2024年02月05日
    浏览(61)
  • 【云原生】Docker镜像的创建 Dockerfile 多阶段构建原理和使用场景

    创建镜像有三种方法,分别为【基于已有镜像创建】、【基于本地模板创建】以及【基于Dockerfile创建】。 (1)首先启动一个镜像,在容器里做修改  docker run -it --name web centos:7 /bin/bash     #启动容器  ​  yum install -y epel-release  #安装epel源  yum install -y nginx         #安装ng

    2024年02月12日
    浏览(55)
  • Docker在windows下使用教程,通过Dockerfile创建镜像/容器,以YOLO系列为例

     通过可视化界面将极大的降低学习难度。  1.1、Docker Desktop下载  下载地址:Docker Desktop: The #1 Containerization Tool for Developers | Docker 应当是这个界面,选择下载即可 1.2、下载完成后需打开window自带的虚拟机       将Hyper-V勾选即打开,勾选后需重启。  1.3、下载WSL,由于是在

    2024年02月05日
    浏览(66)
  • Docker容器:docker镜像的创建及dockerfile

    创建镜像有三种方法:基于现有镜像创建、基于本地模板创建及基于dockerfile创建 1.1 启动镜像 1.2 生成新镜像 2.1 OPENVZ 下载模板 2.2 导入容器生成镜像 3.1 dockerfile结构及分层 (1)dockerfile结构大致分为4个部分 基础镜像信息 维护者信息 镜像操作指令 容器启动时执行指令 Dockerfil

    2024年02月11日
    浏览(57)
  • 【云原生】Docker镜像的创建,Dockerfile

    创建镜像有三种方法,分别为【基于已有镜像创建】、【基于本地模板创建】以及【基于Dockerfile创建】。  通过导入操作系统模板文件可以生成镜像,模板可以从OPENVZ 开源项目下载,下载地址为:   openvz.org/ Download/template/precreated  联合文件系统(UnionFS )  Union文件系统是

    2024年02月15日
    浏览(50)
  • docker 镜像的创建dockerfile 和数据卷

    基于现有的镜像创建镜像 docker commit 基于模板创建镜像 模板可以从OPENVZ开源项目下载 基于dockerfile创建 Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)

    2024年02月09日
    浏览(42)
  • Docker 的数据管理与Dockerfile 镜像的创建

    ------------------Docker 的数据管理--------------------- 管理 Docker 容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器(DataVolumes Containers)。 1.数据卷 数据卷是一个供容器使用的特殊目录,位于容器中。可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见

    2024年02月07日
    浏览(39)
  • Docker容器与虚拟化技术:Docker镜像创建、Dockerfile实例

    目录 一、理论 1.Docker镜像的创建方法 2.Docker镜像结构的分层 3.Dockerfile 案例 4.构建Systemctl镜像(基于SSH镜像) 5.构建Tomcat 镜像 6.构建Mysql镜像 二、实验 1.Docker镜像的创建 2. Dockerfile 案例 3.构建Systemctl镜像(基于SSH镜像) 三、问题 1.nginx网页打不开  2.Apache容器启动一直为Ex

    2024年02月12日
    浏览(67)
  • SpringBoot项目 使用Dockerfile创建镜像与容器

    这里我使用的是云服务器,Centos7-Linux操作系统 需要以下环境支持 1、maven环境 2、java环境 3、springboot项目 maven环境 可以去我这个博客了解\\\'\\\'配置MAVEN环境-CSDN博客\\\'\\\' java环境 可以去\\\'\\\' java环境变量配置-CSDN博客\\\'\\\' springboot项目 先来简单创建一个springboot项目 一、进入IDEA的终端 使用

    2024年03月28日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包