Docker CLI `docker commit` 完全指南:从容器变更创建新镜像的原理与实战 CLI开发工具【免费下载链接】cliThe Docker CLI项目地址https://gitcode.com/gh_mirrors/cli5/cli点击查看免费下载导读docker commit是 Docker CLI 中一条用于「把运行中容器的文件系统变更与配置固化成一个新镜像」的核心命令在调试排障如进入交互式 Shell 排查问题后将现场保存下来、把工作数据集导出到其他服务器、以及快速基于手工配置生成镜像等场景中十分实用。读完本文你将掌握docker commit的完整参数语义、--change注入 Dockerfile 指令的方法、提交时容器暂停机制的底层原因以及当前仓库中该命令的 CLI 实现细节与测试验证方式。命令总览docker commit的命令原型如下源自 commit.md 与 container_commit.md 中的命令参考页docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]一句话说明从容器的变更创建一个新的镜像Create a new image from a containers changes。该命令支持两种调用别名语义完全等价docker container commitdocker commit在 CLI 实现 中命令定义同时指定了Use为commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]参数个数限制为 12 个cli.RequiresRangeArgs(1, 2)并在Annotations中声明别名docker container commit, docker commit同时为该命令注册了容器名称的 Shell 补全函数completion.ContainerNames。参数详解名称类型默认值说明-a,--authorstring作者例如John Hannibal Smith hannibala-team.com-c,--changelist将 Dockerfile 指令应用到创建的镜像上-m,--messagestring提交信息commit message--no-pausebool提交时禁用容器暂停补充早期版本还提供过--run标志已移除以及--pause标志v29.0 起弃用目标在 v30.0 移除详见下文「暂停机制与--no-pause」一节。参数在源码中的落地方式在 commit.go 中所有参数被收集到commitOptions结构体并经ContainerCommit客户端方法传递给 Docker Enginetype commitOptions struct { container string reference string pause bool noPause bool comment string author string changes opts.ListOpts }container与reference来自位置参数第一个必填参数是容器名或容器 ID第二个可选参数是目标仓库引用REPOSITORY[:TAG]--change使用opts.NewListOpts(nil)实现可多次指定以叠加多条 Dockerfile 指令执行核心调用如下runCommitresponse, err : dockerCli.Client().ContainerCommit(ctx, options.container, client.ContainerCommitOptions{ Reference: options.reference, Comment: options.comment, Author: options.author, Changes: options.changes.GetSlice(), NoPause: options.noPause, })命令执行成功后CLI 会把 Engine 返回的新镜像 IDresponse.ID打印到标准输出。提交的语义与适用范围将容器的文件变更和设置固化进新镜像是非常有用的操作典型用途包括调试容器通过交互式 Shell 排查问题后把修复现场直接固化为可复用镜像导出工作数据集把一份已经初始化好的数据目录打包成镜像迁移到另一台服务器继续使用。需要特别注意的一个边界提交不包含挂载卷mounted volumes中的任何数据。卷数据存放在容器可写层之外docker commit只捕获容器文件系统的可写层变更。另外文档明确指出见 container_commit.md 的 Description 一节--change选项会把 Dockerfile 指令应用到创建的镜像上受支持的指令集合为CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | ONBUILD | USER | VOLUME | WORKDIR不在该集合内的 Dockerfile 指令如FROM、COPY、RUN等不能通过--change注入。实战示例以下示例均来自该命令的官方参考文档 container_commit.md可直接复制运行。示例一提交一个容器$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c3f279d17e0a ubuntu:24.04 /bin/bash 7 days ago Up 25 hours desperate_dubinsky 197387f1b436 ubuntu:24.04 /bin/bash 7 days ago Up 25 hours focused_hamilton $ docker commit c3f279d17e0a svendowideit/testimage:version3 f5283438590d $ docker images REPOSITORY TAG ID CREATED SIZE svendowideit/testimage version3 f5283438590d 16 seconds ago 335.7 MB命令输出f5283438590d即为新镜像的 ID随后docker images可以看到新镜像以svendowideit/testimage:version3为标签出现。示例二通过--change注入新配置环境变量先用docker inspect查看容器当前的Env配置再通过--change ENV DEBUGtrue在提交时追加环境变量$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c3f279d17e0a ubuntu:24.04 /bin/bash 7 days ago Up 25 hours desperate_dubinsky 197387f1b436 ubuntu:24.04 /bin/bash 7 days ago Up 25 hours focused_hamilton $ docker inspect -f {{ .Config.Env }} c3f279d17e0a [HOME/ PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin] $ docker commit --change ENV DEBUGtrue c3f279d17e0a svendowideit/testimage:version3 f5283438590d $ docker inspect -f {{ .Config.Env }} f5283438590d [HOME/ PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin DEBUGtrue]对比前后两次inspect输出可以看到新镜像的环境变量中成功追加了DEBUGtrue而原有变量保持不变。示例三同时注入CMD与EXPOSE指令--change可以重复使用长选项--change与短选项-c等价一次提交注入多条指令$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c3f279d17e0a ubuntu:24.04 /bin/bash 7 days ago Up 25 hours desperate_dubinsky 197387f1b436 ubuntu:24.04 /bin/bash 7 days ago Up 25 hours focused_hamilton $ docker commit --changeCMD [apachectl, -DFOREGROUND] -c EXPOSE 80 c3f279d17e0a svendowideit/testimage:version4 f5283438590d $ docker run -d svendowideit/testimage:version4 89373736e2e7f00bc149bd783073ac43d0507da250e999f3f1036e0db60817c0 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 89373736e2e7 testimage:version4 apachectl -DFOREGROU 3 seconds ago Up 2 seconds 80/tcp distracted_fermat c3f279d17e0a ubuntu:24.04 /bin/bash 7 days ago Up 25 hours desperate_dubinsky 197387f1b436 ubuntu:24.04 /bin/bash 7 days ago Up 25 hours focused_hamilton从docker run与后续docker ps的结果可以看到新镜像启动后默认命令已变为apachectl -DFOREGROUND并暴露了80/tcp端口——这正是CMD与EXPOSE指令生效的直接证据。暂停机制与--no-pause为什么默认要暂停容器默认情况下被提交的容器及其中的进程在提交期间会被暂停直到镜像固化完成后再恢复。文档中对此给出的解释是暂停可以降低提交过程中遇到数据损坏的可能性减少正在写入的文件系统状态被不一致地捕获的风险。--no-pause与--pause的演进当前主推选项为--no-pausebool默认false置为true即禁用提交期间的自动暂停历史上曾使用--pause短选项-p控制该行为。在 commit.go 中可以看到--pause标志自 v29.0 起被标记为弃用flags.MarkDeprecated并在代码注释中注明deprecated in v29, can be removed in v30根据 deprecated.md 的说明--pause自 Docker v1.1.0 起默认开启以保证提交一致性v29.0 中它被--no-pause取代v29.0 仍可使用但会打印弃用警告计划在 CLI v30 中移除源码中还针对两个标志同时出现做了互斥校验如果--pause与--no-pause同时被显式指定会直接返回错误conflicting options: --no-pause and --pause cannot be used together。暂停与不暂停的选择建议对正在写入大量数据、对一致性敏感的容器保留默认行为提交时暂停最安全若容器承载实时服务、不希望提交瞬间造成服务中断可使用--no-pause关闭暂停但需自行评估快照不一致的风险。源码实现的调用链与测试验证调用链docker commit在 CLI 侧的完整调用链为cobra 命令解析newCommitCommand → RunE 校验参数个数与标志冲突RequiresRangeArgs / pause 与 no-pause 互斥 → runCommit 组装 client.ContainerCommitOptions → dockerCli.Client().ContainerCommit(...) 调用 Docker Engine API → 输出新镜像 ID从源码结构可以推断ContainerCommit是client.ContainerCommitOptions包含Reference、Comment、Author、Changes、NoPause等字段与 Engine 侧容器提交接口之间的唯一桥接点CLI 本身不直接接触镜像文件系统操作。测试用例佐证commit_test.go 通过test.NewFakeCli与fakeClient对命令行为做了完整验证可以直接反推参数的真实传递路径TestRunCommit以--author、--change EXPOSE 80、--message、--no-pause及容器 ID 构造命令断言传给客户端回调的ContainerCommitOptions中Author、Changes、Comment、NoPause以及容器 ID 全部正确且命令输出恰好为新镜像 IDimage-id\nTestRunCommitClientError验证当底层客户端返回错误时命令会把错误原样向上传递assert.ErrorIs。这两条用例从侧面印证CLI 侧的核心职责就是解析标志 → 组装ContainerCommitOptions→ 转发给 Engine → 打印结果 ID错误则直接透传。常见问题与使用建议提交出来的镜像太大提交会把容器整个可写层固化包含运行期间产生的全部临时文件。提交前建议先清理临时缓存、日志等无用数据。想精确控制镜像配置更推荐写 Dockerfile 并用docker build构建docker commit更适合临时救场和把调试现场固化下来的场景二者定位不同。--change支持哪些指令仅支持CMD、ENTRYPOINT、ENV、EXPOSE、LABEL、ONBUILD、USER、VOLUME、WORKDIR这 9 种其他 Dockerfile 指令会报错。提交后忘记录入仓库docker commit生成的新镜像可用docker tag重新打标或直接再次提交到新的REPOSITORY[:TAG]引用。延伸阅读命令参考页commit.md、完整版 container_commit.md含全部示例与说明CLI 实现cli/command/container/commit.go单元测试cli/command/container/commit_test.go弃用说明docs/deprecated.md--pause标志的弃用时间线相关文档docs/reference/commandline/container.md容器命令族索引赞分享CLI开发工具【免费下载链接】cliThe Docker CLI项目地址https://gitcode.com/gh_mirrors/cli5/cli点击查看免费下载相关推荐tldr 速查手册实战解析用 docker container commit 从容器变更创建镜像tldr 速查手册实战解析用 docker container commit 从容器变更创建镜像 本指南以 tldr 开源速查手册中的 docker cont文档教程知识库Buzz Mac 装完打不开三步选对芯片版本本地语音转文字一次装好Buzz Mac 装完打不开三步选对芯片版本本地语音转文字一次装好 Buzz 是一款在你电脑上本地离线完成语音转文字和翻译的开源工具。Buzz Mac 安装CLI开发工具Docker CLI 的 docker commit 命令把容器变更固化为镜像及其源码实现剖析Docker CLI 的 docker commit 命令把容器变更固化为镜像及其源码实现剖析 docker commit 用于从已运行的容器中生成一个新镜像CLI开发工具上一篇告别表单安全隐患jQuery Validation移动支付场景实战指南下一篇rr源码中的性能优化从算法选择到缓存利用的实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考