Docker-玩转 Docker 镜像:从拉取、构建到发布

Docker-玩转 Docker 镜像:从拉取、构建到发布

文章目录

  • [Docker-玩转 Docker 镜像:从拉取、构建到发布](#Docker-玩转 Docker 镜像:从拉取、构建到发布)
    • 摘要
    • 一、镜像是什么?为什么它是只读的?
      • [1.1 镜像的本质:分层文件系统](#1.1 镜像的本质:分层文件系统)
      • [1.2 镜像 ≠ 容器](#1.2 镜像 ≠ 容器)
    • [二、从 Docker Hub 拉取镜像](#二、从 Docker Hub 拉取镜像)
      • [2.1 查找镜像](#2.1 查找镜像)
      • [2.2 拉取镜像](#2.2 拉取镜像)
    • 三、管理本地镜像:查看、删除与清理
      • [3.1 查看本地镜像](#3.1 查看本地镜像)
      • [3.2 删除镜像](#3.2 删除镜像)
    • [四、实战:用 `docker commit` 创建自定义镜像](#四、实战:用 docker commit 创建自定义镜像)
      • [4.1 场景:定制一个带 `curl` 的 Nginx 镜像](#4.1 场景:定制一个带 curl 的 Nginx 镜像)
        • [步骤 1:启动基础容器](#步骤 1:启动基础容器)
        • [步骤 2:在容器内安装 curl](#步骤 2:在容器内安装 curl)
        • [步骤 3:提交为新镜像](#步骤 3:提交为新镜像)
        • [步骤 4:验证新镜像](#步骤 4:验证新镜像)
      • [4.2 `docker commit` 的局限性](#4.2 docker commit 的局限性)
    • 五、镜像标签(Tag)与推送(Push)
      • [5.1 为镜像打标签](#5.1 为镜像打标签)
      • [5.2 推送镜像到私有仓库(以阿里云为例)](#5.2 推送镜像到私有仓库(以阿里云为例))
    • 六、常见误区与最佳实践
      • [❌ 误区 1:"镜像越大越好,功能越全越好"](#❌ 误区 1:“镜像越大越好,功能越全越好”)
      • [❌ 误区 2:"每次修改都要重新 pull 整个镜像"](#❌ 误区 2:“每次修改都要重新 pull 整个镜像”)
      • [✅ 最佳实践清单:](#✅ 最佳实践清单:)
    • [七、进阶预告:Dockerfile 才是王道](#七、进阶预告:Dockerfile 才是王道)
    • 结语

关键字: Dockerdocker pulldocker commitDocker Hub私有镜像仓库 UnionFS镜像分层

摘要

镜像,是 Docker 世界的"源代码"。

容器只是它的运行时实例,而镜像决定了容器能做什么、依赖什么、如何启动。

在上一篇《Docker 终极入门》中,我们成功运行了 hello-world 容器,初步理解了镜像与容器的关系。但那只是冰山一角。真正掌握 Docker,必须深入理解镜像的生命周期------如何获取、如何创建、如何管理、如何共享。

本文将带你系统掌握 Docker 镜像的核心操作:从官方仓库拉取镜像、查看本地镜像列表、删除无用镜像,到通过 docker commit 快速构建自定义镜像,并为后续使用 Dockerfile 打下基础。最后,我们还将简要介绍如何将镜像推送到私有仓库(如阿里云容器镜像服务),实现团队协作与持续交付。

准备好了吗?让我们一起"玩转" Docker 镜像!


一、镜像是什么?为什么它是只读的?

1.1 镜像的本质:分层文件系统

Docker 镜像并不是一个单一的文件,而是一个由多层只读文件系统叠加而成的联合文件系统(Union File System,简称 UnionFS)。

每一层代表一次变更:比如安装一个软件包、复制一个配置文件、设置环境变量等。这些层按顺序堆叠,最终形成完整的根文件系统。
Base Layer: OS (e.g., Ubuntu) Layer 1: Install curl Layer 2: Copy app code Layer 3: Set ENV PORT=8080 Top Read-Only Image

这种设计带来两大优势:

  • 高效复用 :多个镜像若基于同一基础镜像(如 ubuntu:22.04),则底层共享,节省磁盘空间;
  • 快速构建:修改某一层时,只需重建该层及之后的层,前面的缓存可直接复用。

💡 当你运行一个容器时,Docker 会在镜像顶部动态添加一个可写层(Container Layer),所有运行时的写入操作(如日志、临时文件)都发生在这里。容器停止后,该层可被丢弃或保留。

1.2 镜像 ≠ 容器

再次强调这个关键区别:

项目 镜像(Image) 容器(Container)
状态 只读、静态 可写、动态(运行时实例)
类比 类(Class) 对象(Object)
存储位置 /var/lib/docker/image/... 镜像 + 可写层
是否可变 不可变 可变(但重启后可写层丢失,除非持久化)

二、从 Docker Hub 拉取镜像

Docker Hub 是官方提供的公共镜像仓库,类似于 GitHub 之于代码。几乎所有主流软件都有官方镜像。

2.1 查找镜像

你可以通过以下方式查找镜像:

  • 浏览网站:搜索 "nginx"、"mysql"、"redis" 等;

  • 使用命令行:

    bash 复制代码
    docker search nginx

    输出示例:

    text 复制代码
    NAME                DESCRIPTION                          STARS   OFFICIAL
    nginx               Official build of Nginx.             18000   [OK]
    jwilder/nginx-proxy Automated Nginx reverse proxy         5800

建议优先选择带 [OK] 标记的官方镜像(Official Images),它们经过安全审计、文档完善、更新及时。

2.2 拉取镜像

使用 docker pull 命令下载镜像:

bash 复制代码
# 拉取最新版 Nginx
docker pull nginx

# 拉取指定版本(强烈推荐!)
docker pull nginx:1.25-alpine

📌 最佳实践 :永远不要在生产环境中使用 latest 标签!它可能随时变动,导致不可预测的行为。应明确指定版本号(如 1.258u292-jre)。


三、管理本地镜像:查看、删除与清理

3.1 查看本地镜像

bash 复制代码
docker images

输出示例:

text 复制代码
REPOSITORY    TAG           IMAGE ID       CREATED        SIZE
nginx         1.25-alpine   a6bd7d1c5b3a   2 weeks ago    42.3MB
hello-world   latest        feb5d9fea6a5   12 months ago  13.3kB
  • REPOSITORY:镜像名(通常对应软件名);
  • TAG :版本标签(如 latest, 1.0, alpine);
  • IMAGE ID:镜像唯一标识(SHA256 哈希值前几位);
  • SIZE:仅显示顶层大小,不包括共享层。

3.2 删除镜像

bash 复制代码
# 删除指定镜像(需先停止并删除相关容器)
docker rmi nginx:1.25-alpine

# 强制删除(即使有容器引用)
docker rmi -f <IMAGE_ID>

# 删除所有未被使用的镜像(悬空镜像 + 无标签镜像)
docker image prune -a

⚠️ 注意 :如果某个镜像正在被容器使用(即使是已停止的容器),Docker 默认不允许删除。可先执行 docker rm $(docker ps -aq) 清理所有容器(谨慎操作!)。


四、实战:用 docker commit 创建自定义镜像

虽然正式项目应使用 Dockerfile,但在调试或快速原型阶段,docker commit 是一个非常实用的技巧。

4.1 场景:定制一个带 curl 的 Nginx 镜像

假设我们需要一个既能运行 Nginx,又能用 curl 测试内部服务的容器。

步骤 1:启动基础容器
bash 复制代码
docker run -it --name my-nginx nginx:alpine sh
步骤 2:在容器内安装 curl
sh 复制代码
# 在容器 shell 中执行
apk add --no-cache curl
curl -I http://127.0.0.1  # 测试是否安装成功(会失败,因为 Nginx 未启动)

💡 注意:此时 Nginx 进程并未运行,因为我们覆盖了默认 CMD(nginx -g 'daemon off;')为 sh

步骤 3:提交为新镜像

另开一个终端,执行:

bash 复制代码
docker commit my-nginx my-nginx-with-curl:v1

现在,my-nginx-with-curl:v1 就包含了 curl 工具!

步骤 4:验证新镜像
bash 复制代码
docker run -d --name test-nginx my-nginx-with-curl:v1
docker exec test-nginx curl -I http://127.0.0.1

输出应包含 HTTP/1.1 200 OK,说明一切正常。

4.2 docker commit 的局限性

虽然方便,但 commit 方式存在明显缺点:

  • 不可追溯:无法知道镜像是如何构建的;
  • 难以复现:手动操作步骤容易遗漏;
  • 镜像臃肿:可能包含临时文件或调试工具。

因此,仅建议用于临时调试。正式项目请使用 Dockerfile(下一篇重点讲解)。


五、镜像标签(Tag)与推送(Push)

5.1 为镜像打标签

你可以为同一镜像设置多个标签:

bash 复制代码
# 为刚创建的镜像添加新标签
docker tag my-nginx-with-curl:v1 registry.cn-hangzhou.aliyuncs.com/your-namespace/my-nginx:v1

格式:<仓库地址>/<命名空间>/<镜像名>:<标签>

5.2 推送镜像到私有仓库(以阿里云为例)

  1. 登录阿里云容器镜像服务

    访问 阿里云容器镜像服务控制台,创建命名空间和镜像仓库。

  2. 登录 Docker Registry

    bash 复制代码
    docker login --username=your-aliyun-account registry.cn-hangzhou.aliyuncs.com
    # 输入密码(可使用访问凭证)
  3. 推送镜像

    bash 复制代码
    docker push registry.cn-hangzhou.aliyuncs.com/your-namespace/my-nginx:v1

✅ 成功后,团队成员即可通过 docker pull 拉取该镜像,实现标准化部署。


六、常见误区与最佳实践

❌ 误区 1:"镜像越大越好,功能越全越好"

正解 :镜像应遵循最小化原则。只包含运行应用所必需的组件。Alpine Linux 镜像(几 MB)远优于 Ubuntu(几百 MB)。

❌ 误区 2:"每次修改都要重新 pull 整个镜像"

正解 :Docker 采用分层拉取。若基础层已存在,只会下载变更层,速度极快。

✅ 最佳实践清单:

  • 明确指定镜像 TAG,避免 latest
  • 优先使用官方或可信来源镜像;
  • 定期清理无用镜像(docker system prune);
  • 敏感信息(密码、密钥)绝不写入镜像;
  • 生产环境使用私有仓库,避免依赖公网。

七、进阶预告:Dockerfile 才是王道

虽然 docker commit 能快速构建镜像,但它无法满足工程化需求。下一讲,我们将深入学习 Dockerfile ------ 一种声明式的镜像构建脚本,让你:

  • 完全掌控构建过程;
  • 实现构建可重复、可审计;
  • 利用缓存加速构建;
  • 编写符合安全规范的镜像。

届时,你会明白为什么所有 CI/CD 流水线都依赖 Dockerfile,而不是 commit


结语

镜像,是 Docker 生态的基石。掌握其拉取、管理、构建与发布,是你迈向 DevOps 和云原生开发的关键一步。

记住:好的镜像 = 小体积 + 明确版本 + 安全可靠 + 可复现

现在,你已经可以自信地说:"我不再只是运行容器,我还能打造属于自己的镜像!"


系列预告

下一篇 → 《Docker 容器生命周期管理:从创建到消亡》

我们将全面掌握 docker runexecstoprm 等核心命令,并理解容器状态机!


参考资料


相关推荐
和光同尘20233 小时前
使用Rancher快速部署K8S集群
docker·云原生·容器·kubernetes·centos·rancher·虚拟机
西京刀客3 小时前
Docker Desktop 替代方案之OrbStack、podman、Rancher Desktop
docker·rancher·podman·orbstack
JohnYan3 小时前
Bun技术评估 - 29 Docker集成
javascript·后端·docker
shixian10304114 小时前
Dify Docker Compose 安装指南
docker·容器·eureka
曦樂~4 小时前
【Docker】Compose
docker·容器·eureka
加上音乐4 小时前
windows—wsl2—docker配置代理以push/pull
windows·docker·容器
青靴9 小时前
用 Docker Compose 管理留言板多容器应用
运维·docker·容器
Radan小哥9 小时前
Docker学习笔记---day002
笔记·学习·docker
roman_日积跬步-终至千里14 小时前
【Docker多节点部署】基于“配置即身份“理念的 Docker 多节点 StarRocks 高可用集群自动化部署方案
java·docker·微服务