如何使用 docker container commit 命令创建新镜像

DockerDockerBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,你将学习如何使用 docker container commit 命令从现有容器创建新的 Docker 镜像。我们将从启动并修改一个容器开始,然后将这些变更提交为一个新的镜像。

你还将探索如何通过新配置提交容器变更,包括设置新的 CMD 和 EXPOSE 指令,展示基于运行容器创建自定义镜像的灵活性。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ContainerOperationsGroup -.-> docker/rm("Remove Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") docker/ImageOperationsGroup -.-> docker/images("List Images") subgraph Lab Skills docker/run -.-> lab-555104{{"如何使用 docker container commit 命令创建新镜像"}} docker/ps -.-> lab-555104{{"如何使用 docker container commit 命令创建新镜像"}} docker/rm -.-> lab-555104{{"如何使用 docker container commit 命令创建新镜像"}} docker/inspect -.-> lab-555104{{"如何使用 docker container commit 命令创建新镜像"}} docker/pull -.-> lab-555104{{"如何使用 docker container commit 命令创建新镜像"}} docker/images -.-> lab-555104{{"如何使用 docker container commit 命令创建新镜像"}} end

启动并修改容器

在这一步骤中,你将学习如何启动一个 Docker 容器并在其中进行修改。我们将使用一个简单的 Ubuntu 镜像来演示这个过程。

首先,让我们拉取 Ubuntu 镜像。这个命令会从 Docker Hub 下载 Ubuntu 镜像到你的本地机器。

docker pull ubuntu:latest

你应该能看到显示镜像正在下载的输出。下载完成后,你就可以基于这个镜像运行容器了。

现在,让我们使用 Ubuntu 镜像运行一个交互式容器。-it 参数用于分配一个伪终端并保持标准输入打开,让你可以与容器的 shell 交互。--name 参数为容器指定一个名称,方便后续引用。

docker run -it --name my-ubuntu ubuntu:latest /bin/bash

运行这个命令后,你将进入容器的 bash shell。你可以通过检查主机名来验证这一点,主机名会显示为容器 ID。

在容器内部,让我们创建一个简单的文件。我们将使用 echo 命令将一些文本写入根目录下名为 hello.txt 的文件中。

echo "Hello from inside the container!" > /hello.txt

你可以使用 cat 命令验证文件是否创建成功以及内容是否正确。

cat /hello.txt

你应该能看到输出 "Hello from inside the container!"。

现在我们已经对容器进行了修改,让我们退出容器的 shell。

exit

你现在回到了主机的终端。容器仍在后台运行。你可以通过列出正在运行的容器来验证这一点。

docker ps

你应该能看到列出的 my-ubuntu 容器。

将容器变更提交为新镜像

在上一步中,我们通过在运行中的容器内创建文件进行了修改。现在,我们将学习如何将这些变更保存为新的 Docker 镜像。这个过程称为提交容器(committing a container)。

提交容器会创建一个包含你对容器文件系统和配置所做更改的新镜像。这对于基于现有镜像创建自定义镜像非常有用。

要提交容器,我们使用 docker commit 命令。基本语法是 docker commit [container_name] [new_image_name]。我们将提交 my-ubuntu 容器,并将新镜像命名为 my-ubuntu-modified

docker commit my-ubuntu my-ubuntu-modified

你应该会看到一长串字符作为输出,这是新创建镜像的 ID。

现在,让我们验证新镜像是否已创建。我们可以使用 docker images 命令列出系统中的所有镜像。

docker images

你应该能在输出中看到 my-ubuntu-modified 和原始的 ubuntu 镜像一起列出。

为了确认更改已保存到新镜像中,让我们基于 my-ubuntu-modified 运行一个新容器,并检查我们在上一步中创建的文件。

docker run -it --name my-ubuntu-test my-ubuntu-modified /bin/bash

进入新容器后,检查 /hello.txt 文件是否存在。

cat /hello.txt

你应该能看到输出 "Hello from inside the container!",这确认了更改已成功提交到新镜像。

现在,退出容器。

exit

最后,让我们清理刚刚创建的测试容器。

docker rm -f my-ubuntu-test

提交包含新配置的容器变更

在这一步骤中,我们将探索如何提交容器变更,同时为生成的镜像包含新的配置设置。这允许你定义诸如容器启动时运行的默认命令或环境变量等特性。

我们将继续使用之前步骤中的 my-ubuntu 容器。首先,让我们停止该容器,因为我们将提交其当前状态。

docker stop my-ubuntu

你应该会看到容器名称 my-ubuntu 作为输出打印出来,表明它已被停止。

现在,让我们提交容器并为新镜像添加一个标签(label)。标签是可以附加到镜像上的键值对,用于添加元数据。我们将添加一个标签来标识我们修改后镜像的版本。我们使用 -c 参数后跟配置指令。

docker commit -c 'LABEL version="1.0"' my-ubuntu my-ubuntu-labeled

你应该会看到新创建镜像的 ID 作为输出。

让我们验证新镜像 my-ubuntu-labeled 是否已创建以及标签是否已应用。我们可以使用 docker inspect 命令查看镜像的详细信息。

docker inspect my-ubuntu-labeled

输出将是一个大型 JSON 对象。在 "Config" 块中查找 "Labels" 部分。你应该能找到 "version": "1.0" 列在那里。

或者,你可以使用带过滤的 docker inspect 来专门检查标签。

docker inspect --format '{{.Config.Labels}}' my-ubuntu-labeled

这个命令将只输出与镜像关联的标签。你应该会看到类似 map[version:1.0] 的内容。

我们还可以在提交过程中添加其他配置,比如设置环境变量。让我们再次提交 my-ubuntu 容器,这次添加一个环境变量。

docker commit -c 'ENV MY_VARIABLE="Hello Docker"' my-ubuntu my-ubuntu-env

使用 docker inspect 验证新镜像和环境变量。

docker inspect --format '{{.Config.Env}}' my-ubuntu-env

你应该会看到类似 [PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin MY_VARIABLE=Hello Docker] 的输出,确认环境变量已设置。

提交包含新 CMD 和 EXPOSE 指令的容器变更

在这最后一步中,我们将学习如何提交容器变更,并为新镜像设置默认命令(CMD)和暴露端口(EXPOSE)。

CMD 指令设置了从镜像启动容器时(未指定命令的情况下)默认执行的命令。EXPOSE 指令告知 Docker 容器在运行时监听指定的网络端口。

我们将再次提交 my-ubuntu 容器,这次设置一个默认命令来打印 /hello.txt 的内容,并暴露 80 端口。

首先,确保 my-ubuntu 容器已停止。

docker stop my-ubuntu

现在,使用 CMDEXPOSE 指令提交容器。注意 CMD 指令是以 JSON 字符串数组的形式提供的。

docker commit -c 'CMD ["cat", "/hello.txt"]' -c 'EXPOSE 80' my-ubuntu my-ubuntu-final

你应该会看到新创建镜像的 ID 作为输出。

让我们使用 docker inspect 验证新镜像 my-ubuntu-finalCMDEXPOSE 配置。

docker inspect --format '{{.Config.Cmd}}' my-ubuntu-final

这应该会输出 [cat /hello.txt],确认默认命令已设置。

现在,让我们检查暴露的端口。

docker inspect --format '{{.Config.ExposedPorts}}' my-ubuntu-final

你应该会看到类似 map[80/tcp:{}] 的输出,表明 80 端口已暴露。

最后,让我们从这个新镜像运行一个容器而不指定命令,看看默认的 CMD 是否生效。

docker run --rm my-ubuntu-final

--rm 标志会在容器退出时自动移除它。由于默认命令是 cat /hello.txt,容器应该会运行,打印 "Hello from inside the container!",然后退出。

你应该会在终端看到打印出的 "Hello from inside the container!"。

这演示了如何提交容器变更并定义结果镜像的默认行为和网络配置。

总结

在本实验中,你学习了如何启动和修改 Docker 容器。你拉取了 Ubuntu 镜像,基于该镜像运行了一个交互式容器,在容器内创建了文件,然后在保持容器运行的状态下退出了容器 shell。

随后,你学习了如何将运行中容器内的变更提交(commit)以创建新的 Docker 镜像。这个过程允许你将容器的当前状态保存为可重复使用的镜像。