在 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 容器中安装 curl
和 vim
:
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 镜像制作系列的第 五篇,后续我们还会介绍更多关于镜像优化、多阶段构建、镜像安全等内容,欢迎持续关注!