Docker:手动制作镜像 [五] —— 通过 docker commit 快速构建镜像

在 Docker 的世界中,构建镜像是最基础也是最重要的操作之一。我们通常推荐使用 ​​Dockerfile​​ 来以声明式的方式定义镜像的构建过程,这种方式具有良好的可读性、可维护性和自动化能力。

但有时候,出于学习、测试、快速验证或者特殊需求的目的,我们可能希望​​不使用 Dockerfile,而是通过手动方式进入容器、安装软件、修改配置,最后将这个"定制化"的容器保存为一个新的镜像​ ​。这种方式就是使用 docker commit命令来​​手动提交容器为镜像​​。

本篇文章是 Docker 镜像制作系列的第 ​​五篇​ ​,将详细介绍如何通过手动方式(即 docker commit)来制作 Docker 镜像。

一、什么是手动制作镜像(docker commit)?

Docker 提供了一个非常直接的命令 docker commit

,它允许你将一个​​正在运行或已停止的容器​​的当前状态保存为一个新的镜像。

简单来说:

你从一个基础镜像启动一个容器,在里面安装软件、修改配置、创建文件,然后通过 docker commit把这个容器"拍"成一个新镜像,以后就可以基于这个新镜像重新启动容器。

这种方式类似于在虚拟机中安装好所有软件后,将整个虚拟机保存为一个模板。

二、手动制作镜像的典型使用场景

虽然不推荐在生产环境中频繁使用,但手动制作镜像在一些场景下仍然非常有用:

  • ​快速测试和验证​​:临时修改容器内容,快速验证某个功能是否可行。

  • ​学习与实验​​:初学者通过手动操作理解镜像和容器的关系。

  • ​紧急修复​​:在无法立即编写 Dockerfile 的情况下,快速保存一个已配置好的容器状态。

  • ​特殊定制​​:某些配置或操作难以通过 Dockerfile 实现,可以手动处理后再提交为镜像。

三、手动制作镜像的步骤

下面我们通过一个完整的例子来演示如何手动制作一个 Docker 镜像。

步骤 1:拉取基础镜像

我们以 Ubuntu 为例:

复制代码
bash复制docker pull ubuntu:latest

或者使用更轻量的 Debian:

复制代码
bash复制docker pull debian:bullseye

步骤 2:启动一个容器并进入交互式 Shell

运行一个容器,并进入其交互式终端:

arduino 复制代码
bash复制docker run -it --name my_manual_container ubuntu:latest /bin/bash

参数说明:

  • -it:以交互模式运行容器,并分配一个伪终端。

  • --name my_manual_container:为该容器指定一个名字,方便后续管理。

  • ubuntu:latest:使用的基础镜像。

  • /bin/bash:启动容器后运行的命令(这里是启动 bash shell)。

此时你已进入容器的命令行环境,可以像操作普通 Linux 系统一样进行操作。

步骤 3:在容器内进行个性化配置

在容器里,你可以执行任意命令,比如安装软件、创建文件、修改配置等。

举个例子,我们在 Ubuntu 容器中安装 curlvim

sql 复制代码
bash复制apt-get update
apt-get install -y curl vim

然后你还可以创建一些文件,比如:

bash 复制代码
bash复制echo "Hello, this is a manually built image!" > /opt/myfile.txt

或者创建一个简单的启动脚本:

bash 复制代码
bash复制echo '#!/bin/bash' > /startup.sh
echo 'echo "Welcome to my custom container!"' >> /startup.sh
echo 'curl ifconfig.me' >> /startup.sh
chmod +x /startup.sh

当你完成所有需要的配置后,可以​​退出容器​​:

bash 复制代码
bash复制exit

此时容器处于​​停止状态​ ​(除非你使用了 --detach模式让它后台运行)。

步骤 4:查看当前所有的容器

使用以下命令查看本地的容器,包括正在运行和已经停止的:

css 复制代码
bash复制docker ps -a

你应该能看到一个名为 my_manual_container的容器,状态是 Exited。

示例输出:

java 复制代码
复制CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS                     PORTS     NAMES
abc123def456   ubuntu:latest  "/bin/bash"   5 minutes ago   Exited (0) 2 minutes ago             my_manual_container

步骤 5:使用 docker commit 提交容器为新镜像

通过以下命令将刚才的容器保存为一个新的镜像:

perl 复制代码
bash复制docker commit my_manual_container my-custom-ubuntu:manual-v1

参数解释:

  • my_manual_container:要提交的容器名称或 ID。

  • my-custom-ubuntu:manual-v1:新镜像的名称与标签,你可以自定义。

提交成功后,你会看到类似如下的输出,显示新镜像的 ID:

makefile 复制代码
复制sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

你可以使用以下命令查看本地的所有镜像,确认新镜像已经存在:

复制代码
bash复制docker images

示例输出:

perl 复制代码
复制REPOSITORY            TAG             IMAGE ID       CREATED         SIZE
my-custom-ubuntu      manual-v1       xxxxxxxxxx     2 minutes ago   200MB
ubuntu                latest          yyyyyyyyyy     3 days ago      72.8MB

步骤 6:基于新镜像启动容器

现在你可以使用你刚刚创建的镜像来启动一个新的容器,验证你的修改是否生效:

bash 复制代码
bash复制docker run -it --rm my-custom-ubuntu:manual-v1 /bin/bash

进入容器后,你可以检查之前安装的软件、创建的文件是否存在:

bash 复制代码
bash复制curl ifconfig.me
vim --version
cat /opt/myfile.txt

如果你之前创建了 /startup.sh,也可以运行它:

bash 复制代码
bash复制./startup.sh

四、手动制作镜像的优缺点

✅ 优点:

  • ​快速​​:无需编写 Dockerfile,适合临时构建和测试。

  • ​直观​​:直接在容器里操作,所见即所得。

  • ​灵活​​:可以进行任意操作,不受 Dockerfile 语法限制。

❌ 缺点:

  • ​不可重复​​:没有明确的构建步骤记录,难以复现和协作。

  • ​难以维护​​:随着修改增多,难以追踪哪些操作被提交到镜像中。

  • ​不适合生产​​:缺乏版本控制、自动化和清晰文档,不推荐用于正式环境。

五、最佳实践建议

虽然 docker commit手动制作镜像很方便,但在实际开发与部署中,我们强烈建议:

​优先使用 Dockerfile 来构建镜像!​

Dockerfile 的优势包括:

  • 构建过程透明、可读、可维护;

  • 支持版本控制(如 Git),便于团队协作;

  • 可以通过 docker build自动化构建,CI/CD 友好;

  • 镜像分层清晰,便于优化和管理。

只有在以下特殊情况下,才考虑使用 docker commit

  • 快速验证某个想法;

  • 临时保存容器状态;

  • 学习 Docker 原理与容器运行机制。

六、总结

项目

手动制作镜像(docker commit)

使用 Dockerfile 构建镜像

构建方式

通过交互式修改容器后提交

通过声明式 Dockerfile 构建

适用场景

学习、测试、临时用途

生产、开发、自动化构建

可维护性

差,难以追踪更改

好,每一步清晰可控

推荐程度

⭐⭐(适合特定场景)

⭐⭐⭐⭐⭐(强烈推荐)

七、结语

通过本篇文章,我们学习了如何使用 docker commit命令​​手动将一个配置好的容器保存为新的 Docker 镜像​​。这是 Docker 镜像构建的一种"手动"方式,虽然不如 Dockerfile 灵活和规范,但在某些场景下仍然有其价值。

本篇是 Docker 镜像制作系列的第 ​​五篇​​,后续我们还会介绍更多关于镜像优化、多阶段构建、镜像安全等内容,欢迎持续关注!

相关推荐
幽络源小助理2 小时前
MySQL实战优化高手教程 – 从架构原理到生产调优
数据库·mysql·架构
Ashlee_code2 小时前
香港券商智能櫃台系統技術解決方案——融合跨境清算與AI風控,助力券商把握滬港雙市爆發機遇**
java·科技·金融·重构·架构·系统架构·php
LLLLYYYRRRRRTT2 小时前
WordPress (LNMP 架构) 一键部署 Playbook
linux·架构·ansible·mariadb
Runing_WoNiu2 小时前
Redis主从架构、哨兵模式及集群比较
数据库·redis·架构
kuxku3 小时前
下一代前端工具链浅析
前端·架构
无责任此方_修行中4 小时前
从 HTTP 轮询到 MQTT:我们在 AWS IoT Core 上的架构演进与实战复盘
后端·架构·aws
天上掉下来个程小白5 小时前
微服务-01.导入黑马商城
java·微服务·架构
程思扬6 小时前
Nextcloud容器化部署革新:Docker+Cpolar构建高效私有云远程访问新架构
docker·容器·架构