当我制作Docker镜像时,
使用commit命令和使用Dockerfile来构建命令会有什么区别吗?我是从镜像大小和算法方面来说的。
当我制作Docker镜像时,
使用commit命令和使用Dockerfile来构建命令会有什么区别吗?我是从镜像大小和算法方面来说的。
docker commit
,都会创建一个新的图像。docker build
才会创建一个新的图像。docker build
将给出一致的图像大小,因为它是基于 Dockerfile
中指定的内容构建的。而 docker commit
的图像大小取决于容器的当前状态。如果您在容器运行后删除了很多东西,您可能会得到较小的图像,反之亦然。docker build
的最终产品本质上是提交。docker build
就像 git clone
,而 docker commit
就像 git commit
。最好的方法是尝试一下(或比较github上的代码,但那时已经过了我的睡觉时间)。生成的图像中有一些细微的差别。主要是有一些引用不在那里,这些引用用于缓存以前的构建。而且,在我的例子中,与容器相关联的命令是不同的。老实说,我无法确定为什么docker commit
版本更小,但两个图像都基于相同的父级层,并且非常相似。对于可维护性来说,Dockerfile将更易于管理。
$ cat df.apt-get-git
FROM debian:latest
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
vim \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
$ docker build -t test-git:dockerfile -f df.apt-get-git .
Sending build context to Docker daemon 248.3 kB
Step 1 : FROM debian:latest
---> 7b0a06c805e8
Step 2 : RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y git vim && apt-get clean && rm -rf /var/lib/apt/lists/*
---> Running in 44588d9cdef4
Get:1 http://security.debian.org jessie/updates InRelease [63.1 kB]
Ign http://deb.debian.org jessie InRelease
....
Updating certificates in /etc/ssl/certs... 174 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
Processing triggers for systemd (215-17+deb8u5) ...
---> 01cb5ddcddd1
Removing intermediate container 44588d9cdef4
Successfully built 01cb5ddcddd1
$ docker inspect test-git:dockerfile
[
{
"Id": "sha256:01cb5ddcddd101e498ff9e09e4cb4efad85f49a3b87c5792c807ebccedc83977",
"RepoTags": [
"test-git:dockerfile"
],
"RepoDigests": [],
"Parent": "sha256:7b0a06c805e8f23807fb8856621c60851727e85c7bcb751012c813f122734c8d",
"Comment": "",
"Created": "2016-12-28T02:55:23.950610688Z",
"Container": "44588d9cdef49728a012a5a19657ac2b97b6de191ece375607a22043ae993043",
"ContainerConfig": {
"Hostname": "397f80c505a4",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"apt-get update \u0026\u0026 DEBIAN_FRONTEND=noninteractive apt-get install -y git vim \u0026\u0026 apt-get clean \u0026\u0026 rm -rf /var/lib/apt/lists/*"
],
"ArgsEscaped": true,
"Image": "sha256:7b0a06c805e8f23807fb8856621c60851727e85c7bcb751012c813f122734c8d",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {}
},
"DockerVersion": "1.12.3",
"Author": "",
"Config": {
"Hostname": "397f80c505a4",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"ArgsEscaped": true,
"Image": "sha256:7b0a06c805e8f23807fb8856621c60851727e85c7bcb751012c813f122734c8d",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 245152070,
"VirtualSize": 245152070,
"GraphDriver": {
"Name": "aufs",
"Data": null
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:f96222d75c5563900bc4dd852179b720a0885de8f7a0619ba0ac76e92542bbc8",
"sha256:e839e7442c5bbd0a3843822997bcd6830f88fc03417ad6dfd4cc9cb9c6ce0dfa"
]
}
}
]
$ docker run --name test-git-commit debian:latest /bin/sh -c 'apt-get update \
> && DEBIAN_FRONTEND=noninteractive apt-get install -y \
> git \
> vim \
> && apt-get clean \
> && rm -rf /var/lib/apt/lists/*'
Get:1 http://security.debian.org jessie/updates InRelease [63.1 kB]
...
Updating certificates in /etc/ssl/certs... 174 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
Processing triggers for systemd (215-17+deb8u5) ...
$ docker commit test-git-commit test-git:commit
sha256:141c140e3bb0b8a865e58cfd1674f9dac70623c6537f362b15a0ec0a8edbfd0c
$ docker inspect test-git:commit
[
{
"Id": "sha256:141c140e3bb0b8a865e58cfd1674f9dac70623c6537f362b15a0ec0a8edbfd0c",
"RepoTags": [
"test-git:commit"
],
"RepoDigests": [],
"Parent": "sha256:7b0a06c805e8f23807fb8856621c60851727e85c7bcb751012c813f122734c8d",
"Comment": "",
"Created": "2016-12-28T02:57:50.962700517Z",
"Container": "5160a31123f3594255a03c42ab72a41ec1fbe72a394923608c8e5654e5d3027b",
"ContainerConfig": {
"Hostname": "5160a31123f3",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"apt-get update \\\n \u0026\u0026 DEBIAN_FRONTEND=noninteractive apt-get install -y \\\n git \\\n vim \\\n \u0026\u0026 apt-get clean \\\n \u0026\u0026 rm -rf /var/lib/apt/lists/*"
],
"Image": "debian:latest",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "1.12.3",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"apt-get update \\\n \u0026\u0026 DEBIAN_FRONTEND=noninteractive apt-get install -y \\\n git \\\n vim \\\n \u0026\u0026 apt-get clean \\\n \u0026\u0026 rm -rf /var/lib/apt/lists/*"
],
"Image": "",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 236898630,
"VirtualSize": 236898630,
"GraphDriver": {
"Name": "aufs",
"Data": null
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:f96222d75c5563900bc4dd852179b720a0885de8f7a0619ba0ac76e92542bbc8",
"sha256:c1fd858a68b921981cd15793cbf673a7794d950bb5cc70769ba250df7b7439f9"
]
}
}
]
docker build
将为Dockerfile中的每个指令生成一个层,这就是为什么将具有类似缓存要求的指令合并成一个最佳实践的原因。 - BMitch
Dockerfile
中的每个RUN
命令都会创建一个层。如果要使用docker commit
完成此操作,则可能需要在容器内部跳进和跳出以在运行下一个命令之前进行提交。 - Andy