简介
在本实验中,你将学习如何使用 docker container commit
命令从现有容器创建新的 Docker 镜像。我们将从启动并修改一个容器开始,然后将这些变更提交为一个新的镜像。
你还将探索如何通过新配置提交容器变更,包括设置新的 CMD 和 EXPOSE 指令,展示基于运行容器创建自定义镜像的灵活性。
在本实验中,你将学习如何使用 docker container commit
命令从现有容器创建新的 Docker 镜像。我们将从启动并修改一个容器开始,然后将这些变更提交为一个新的镜像。
你还将探索如何通过新配置提交容器变更,包括设置新的 CMD 和 EXPOSE 指令,展示基于运行容器创建自定义镜像的灵活性。
在这一步骤中,你将学习如何启动一个 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
指令告知 Docker 容器在运行时监听指定的网络端口。
我们将再次提交 my-ubuntu
容器,这次设置一个默认命令来打印 /hello.txt
的内容,并暴露 80 端口。
首先,确保 my-ubuntu
容器已停止。
docker stop my-ubuntu
现在,使用 CMD
和 EXPOSE
指令提交容器。注意 CMD
指令是以 JSON 字符串数组的形式提供的。
docker commit -c 'CMD ["cat", "/hello.txt"]' -c 'EXPOSE 80' my-ubuntu my-ubuntu-final
你应该会看到新创建镜像的 ID 作为输出。
让我们使用 docker inspect
验证新镜像 my-ubuntu-final
的 CMD
和 EXPOSE
配置。
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 镜像。这个过程允许你将容器的当前状态保存为可重复使用的镜像。