Docker Commit 命令

Docker 中用于将容器的修改提交为新镜像的命令,当我们对运行中的容器进行了配置修改、软件安装等操作后,可以通过该命令将这些变更固化为一个新的镜像,以便后续复用或分发。

基本语法

如下命令可以允许我们将容器的当前状态保存为一个新的镜像。当我们在容器中安装了新软件或修改了配置,需要保存这些更改的时候,我们可以把该镜像打包为一个容器进行发布。

1
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
  • CONTAINER:要提交的容器 ID 或名称。

  • REPOSITORY[:TAG](可选):新镜像的名称和标签,格式为仓库名:标签名

  • 常用参数

    参数 作用
    -a, --author 指定镜像作者,如--author "ergoutree"
    -c, --change 在提交时添加 Dockerfile 指令(如CMDENV),会应用到新镜像中。
    -m, --message 添加提交信息,类似 Git 的提交说明。
    -p, --pause 提交时暂停容器(默认行为),可通过-p=false禁用。

参数讲解

docker commit --help的内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ergoutree@ergoutree-virtual-machine:~/my-python-project$ docker commit --help

Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Create a new image from a container's changes

Aliases:
docker container commit, docker commit

Options:
-a, --author string Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Commit message
-p, --pause Pause container during commit (default true)

-a, --author

这个选项允许我们为新创建的镜像指定作者信息。它的格式通常是”名字 <邮箱>“。例如

1
docker commit -a "ergoutree <john@example.com>" my_container my_new_image:v1

-c, --change

允许我们在创建新镜像时应用Dockerfile指令。这意味着我们可以在提交过程中修改容器的配置。

1
docker commit -c "ENV DEBUG=true" -c "EXPOSE 8080" my_container my_debug_image:v1

这个命令会创建一个新镜像,设置了一个环境变量DEBUG并暴露了8080端口。这个选项使得docker commit更加灵活,允许我们在不使用Dockerfile的情况下对镜像进行一些配置更改。

-m, --message

类似于Git提交,这个选项允许我们为镜像提交添加一条描述性消息。

1
docker commit -m "Added nginx configuration for load balancing" my_nginx_container my_lb_nginx:v1

这样,当我们之后查看镜像历史时,就能清楚地知道这个镜像的用途和它与其他镜像的区别。

-p, --pause

这个选项控制是否在提交过程中暂停容器。默认情况下,它被设置为true。这意味着Docker会在创建镜像时暂时停止容器的所有进程,以确保文件系统处于一致状态。如果我们确定暂停容器不会影响到正在进行的操作,可以使用--pause=false来避免暂停:

1
docker commit --pause=false my_container my_new_image:v1

综合实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 首先,启动一个Ubuntu容器并在其中安装Nginx
docker run -it --name custom_nginx ubuntu:latest
apt-get update && apt-get install -y nginx

# 在另一个终端中,使用docker commit创建新镜像,应用多个选项
docker commit \
-a "Jane Smith <jane@example.com>" \
-m "Created custom Nginx image with optimized configuration" \
-c "ENV NGINX_VERSION=1.18.0" \
-c "EXPOSE 80 443" \
--pause=true \
custom_nginx \
my-optimized-nginx:v1.0

# 这将创建一个新的Nginx镜像,包含自定义配置和元数据

docker 提交镜像命令

1
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 启动一个Ubuntu容器并进入交互模式
    docker run -it ubuntu bash

    # 在容器内安装Vim(示例操作)
    apt-get update && apt-get install -y vim

    # 退出容器
    exit

    # 获取容器ID(通过docker ps -a查看)
    CONTAINER_ID=$(docker ps -a -q --latest)

    # 提交容器,添加标签
    docker commit \
    -a "ergoutree" \
    -m "Installed Vim in Ubuntu" \
    $CONTAINER_ID \
    my-ubuntu:with-vim

    # 查看本地镜像列表
    docker images
    image-20250708202436484

    装好vim后,尝试打包提交

    image-20250708202638575

​ 可以看到是出现了新的镜像的,但是由于我操作失误忘记命名变成虚悬镜像了

image-20250708202757721

docker提交新镜像的注意

  1. 镜像分层commit会创建一个新的镜像层,包含自容器创建以来的所有更改。过多的层会导致镜像臃肿,建议使用 Dockerfile 替代(Dockerfile 构建的镜像更简洁)。
  2. 数据持久化commit仅保存容器的文件系统变化,不保存挂载的卷(Volumes)中的数据。
  3. 安全性风险:容器中可能包含敏感信息(如密码、密钥),提交前应清理这些数据。
  4. 替代方案:优先使用 Dockerfile 构建镜像,因为它可重现、可维护,且更符合实践。commit适用于快速迭代或调试场景。

本地镜像发布

到 Docker 官方(Docker Hub)

  1. 注册账号:访问Docker Hub 官网,注册并登录账号。

    image-20250708203943428
  2. 登录后,点击左侧导航栏中的Hub ,会出现一个下拉菜单。在下拉菜单中,点击Repositories 选项,进入仓库管理页面。然后就能看到创建仓库了

    填写仓库名称,例如 “my - nginx - image”,并选择仓库类型(公有或私有),完成后点击 “Create”。

    image-20250708204716159
  3. 标记本地镜像

    • 首先查看本地已有的镜像,使用命令docker images,会列出本地所有镜像的相关信息,包括REPOSITORY(仓库名)、TAG(标签)、IMAGE ID等。
    • 假设本地有一个名为 “nginx - local” 的镜像,标签为 “latest”,要将其推送到 Docker Hub 上名为 “my - nginx - image” 的仓库,并标记为 “v1.0” 版本。使用以下命令打标签:docker tag nginx - local:latest your-username/my-nginx-image:v1.0,其中 “your - username” 替换为你的 Docker Hub 用户名。
  4. 推送镜像到 Docker Hub

    • 使用docker push命令将标记好的镜像推送到 Docker Hub,命令格式为docker push <username>/<repository>:<tag>
    • 对于前面的例子,执行docker push your - username/my - nginx - image:v1.0。Docker 会开始逐层上传镜像的层数据,并显示上传进度,上传完成后,可在 Docker Hub 仓库页面查看已上传的镜像。

到阿里云

  1. 首先点开阿里云的容器镜像服务,点击个人版实例,然后需要先创建一个命名空间,然后才能创建镜像仓库。在左侧导航栏找到 “命名空间” 并点击,接着点击 “创建命名空间” 按钮。为命名空间取个合适的名称,比如my-namespace,再选择 “公开” 或者 “私有” 的类型,最后点击 “确定”。

    image-20250709083507320

    点击左侧导航栏的 “镜像仓库”,再点击 “创建镜像仓库”。选择 “本地仓库”,填入仓库名称,例如my-app,还可以添加描述信息。选择之前创建的命名空间,设置仓库类型,然后点击 “创建”。

    image-20250709083526327
  2. 创建好仓库后,进入仓库详情页,能看到类似registry.cn-hangzhou.aliyuncs.com/my-namespace/my-app这样的推送地址。点击右上角的 “凭证管理”,按照提示创建并记录好访问凭证,也就是用户名和密码。用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。可以在访问凭证页面修改凭证密码。

    1
    docker login --username=你的阿里云账号 registry.cn-hangzhou.aliyuncs.com
    image-20250709083915639
  3. 之后从Registry中拉取镜像,先通过以下命令查看正在运行的容器 ID。

    1
    docker ps -a

    假设你有一个运行中的容器,使用下面的命令基于该容器创建镜像。其中,CONTAINER_ID是前面查看到的容器 ID,IMAGE_TAG是你给镜像设定的标签,比如v1.0

    1
    docker commit CONTAINER_ID registry.cn-hangzhou.aliyuncs.com/my-namespace/my-app:IMAGE_TAG

    如果需要为同一个镜像添加多个标签,可使用以下命令。

    1
    docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
  4. 执行以下命令将镜像推送到阿里云容器镜像服务。

    如果你之前传过,或者你要传别人的然后自己修改的,先从 Registry 拉取镜像

    1
    docker pull crpi-nko70rgegzb030yk.cn-beijing.personal.cr.aliyuncs.com/my-vim-ubuntu/vim-ubuntu:[镜像版本号]

    这里是直接将镜像推送到Registry

    1
    2
    3
    $ docker login --username=ErgouTree crpi-nko70rgegzb030yk.cn-beijing.personal.cr.aliyuncs.com
    $ docker tag [ImageId] crpi-nko70rgegzb030yk.cn-beijing.personal.cr.aliyuncs.com/my-vim-ubuntu/vim-ubuntu:[镜像版本号]
    $ docker push crpi-nko70rgegzb030yk.cn-beijing.personal.cr.aliyuncs.com/my-vim-ubuntu/vim-ubuntu:[镜像版本号]
    image-20250709090212458

​ 可以看到已经推送上去了。

  1. 推送完成后,回到阿里云容器镜像服务控制台,进入镜像仓库详情页,点击 “版本管理”,就能看到刚推送的镜像标签。

    image-20250709090325166
    image-20250709090345826

本地镜像发布到私有库

什么是私有库

我们把镜像发布到 Docker Hub 和 阿里云,都是放到公共镜像仓库,但是由于机密性问题,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。

Docker Registry是官方提供的工具,可以用于构建私有镜像仓库

先跑起来

image-20250711083954410

先更新我们需要推送的仓库

1
2
apt-get update
apt-get install net-tools
image-20250711083245261

使用ipconfig,得到 Docker 网桥的 IP 地址 172.17.0.3,如果你是Ubuntu的虚拟机,通常是这个

image-20250711085344998

下载 Docker Registry

1
docker pull registry
image-20250711082531373

要运行一个 Docker Registry 容器,以此来搭建本地私有仓库,相当于本地有个Docker Hub

1
docker run -d -p 5000:5000 --restart=always --name registry registry:2

默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便于宿主机联调

  • -d:后台运行,不会阻塞当前会话。
  • -p 5000:5000--publish:将容器内部端口映射到主机的端口(格式为 主机端口:容器端口)。
    • -p:指定端口,-P:随机端口
  • –restart=always:设置容器的重启策略,确保容器始终运行。
  • –name registry:为容器指定一个自定义名称
  • registry:2:指定要运行的镜像及其标签。

把更新过的镜像进行推送

1
docker commit -m "添加网络工具" -a "ergoutree" 0041ea2e60fe vimunbuntu:latest

然后为镜像添加标签

1
docker tag vimunbuntu:latest localhost:5000/vimunbuntu:latest
image-20250711084520951

完成标签添加后,就可以将镜像推送到本地私有仓库了

1
docker push localhost:5000/vimunbuntu:latest
image-20250711083552567

使用 curl 命令来确认镜像是否已成功推送到本地仓库:

1
curl http://localhost:5000/v2/_catalog
image-20250711083601212

然后发下述命令,查询 Docker 私有仓库中镜像标签信息的请求命令,向本地 Docker 私有仓库发送 Get 请求,查询 vimunbuntu 镜像的所有可用标签,可以看到

1
curl -XGET http://172.17.0.1:5000/v2/vimunbuntu/tags/list
image-20250711085357678

成功推送到本地了