Docker 镜像

镜像(Image)是 Docker 的"安装包"——一个只读的模板,包含应用运行所需的所有文件、库和配置。这一章我们把镜像相关的常用命令一次性讲透:怎么找、怎么下、怎么看、怎么删、怎么搬。

1. docker pull:下载镜像

镜像从"仓库"下载到本地,叫 pull。这是学 Docker 后输入的第一条命令:

# 从镜像仓库下载镜像到本地

# 基本用法:docker pull 镜像名:标签
docker pull nginx                  # 不写标签,等价于 nginx:latest(不推荐)
docker pull nginx:1.25             # 指定版本,生产环境必须这样
docker pull nginx:1.25-alpine      # alpine 版,镜像体积小很多
docker pull python:3.12-slim       # slim 版,精简但保留常用库

# 完整镜像名:仓库名/镜像名:标签
docker pull library/nginx:latest   # library 是官方仓库,可省略
docker pull username/myapp:v1.0    # 用户镜像,username 必填
docker pull registry.cn-hangzhou.aliyuncs.com/ns/app:1.0   # 第三方仓库

# 拉取时分层下载,每层独立显示进度
# Already exists: a48076...         ← 这层本地已有,直接复用
# Pull complete: 8d30ef9e...         ← 这层刚下载完

标签(tag)很重要nginx:1.25 是明确版本,nginx:latest 是"最新"——但 latest 只是默认标签名,不代表真的最新,而且今天拉的 latest 和明天的可能完全不同。生产环境永远不要用 latest,否则没法回滚。

2. docker search:搜索镜像

不确定镜像叫什么名字时,可以命令行搜:

# 在 Docker Hub 搜索镜像(需要联网)

docker search nginx
# NAME    DESCRIPTION   STARS   OFFICIAL   AUTOMATED
# nginx   Official...   20000   [OK]
# bitnami/nginx  ...    300

# 只看官方镜像(带 [OK] 标记,质量有保证)
docker search --filter is-official=true nginx

# 只看收藏数 50 以上的
docker search --filter stars=50 nginx

# 注意:search 不能搜具体标签,只能搜镜像名
# 想看某镜像有哪些版本,直接访问 hub.docker.com/_/nginx/tags

选镜像的两个原则:优先看 OFFICIAL 标记(官方维护,安全);其次看 STARS 数(社区认可度)。非官方镜像(bitnami/nginx 这种)虽然功能更多,但要确认维护方靠谱。

3. docker images:列出本地镜像

# 列出本地所有镜像

docker images                    # 等价于 docker image ls
# REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
# nginx        1.25      605c77e624dd   2 weeks ago    142MB
# python       3.12      2f56ecf2ab44   3 weeks ago    1.0GB

# 只看特定镜像
docker images nginx
docker images "python:*"         # 支持通配符

# 只看镜像 ID(脚本里常用)
docker images -q

# 看中间层镜像(包括没有被任何容器使用的)
docker images -a

# 按大小排序(找占空间的)
docker images --format "{{.Repository}}:{{.Tag}} {{.Size}}" | sort -k2 -h

注意 IMAGE ID 是镜像内容的哈希,同名不同标签的镜像可能 ID 相同(本质是同一个)。磁盘空间是按"层"去重的,所以拉 nginx:1.25 后再拉 nginx:1.25-alpine,共享的层不会重复占空间。

4. docker tag / rmi:打标签与删除

# 给镜像打标签 / 删除镜像

# 打标签:本质是"起别名",两个 tag 指向同一个镜像
docker tag nginx:1.25 mynginx:1.25
docker tag nginx:1.25 yourname/nginx:v1   # 准备推到 Docker Hub 前必做

# 删除镜像:必须先删除依赖它的所有容器
docker rmi nginx:1.25            # 按 仓库名:标签
docker rmi 605c77e624dd          # 按镜像 ID
docker rmi -f nginx:1.25         # 强制删除(有容器在用也删,慎用)

# 删除所有未被使用的镜像(释放磁盘)
docker image prune               # 只删悬空镜像(dangling,无标签)
docker image prune -a            # 删除所有未被容器使用的镜像

# 清理一切:停止的容器、无用网络、悬空镜像、构建缓存
docker system prune -a           # 加 --volumes 连数据卷一起删,极度危险

删除镜像时如果报 "image is being used by stopped container",说明有容器(哪怕是停止的)在用它。先 docker rm 容器名 删容器,再 docker rmi 镜像docker system prune -a 是"一键大扫除",会删掉所有未被使用的镜像,执行前要想清楚。

5. docker save / load:离线搬运镜像

有些环境(内网、客户现场)没法连 Docker Hub,需要把镜像打包成文件搬过去:

# 镜像导出与导入(离线传输场景)

# 把镜像保存成 tar 文件(包含所有层)
docker save -o nginx.tar nginx:1.25
# 或管道写法
docker save nginx:1.25 | gzip > nginx.tar.gz

# 拷到内网机器,再导入(完整保留分层信息)
docker load -i nginx.tar
docker load < nginx.tar.gz

# save / load vs export / import 的区别:
#   save/load  :保留镜像完整历史和分层,推荐
#   export/import:把容器拍扁成单层文件,丢失历史,文件更小但不可分层缓存

# 查看镜像历史(每条 Dockerfile 指令对应一层)
docker history nginx:1.25
# IMAGE      CREATED   CREATED BY      SIZE
# 605c77e..  2 weeks   /bin/sh -c ...   142MB
# <missing>  2 weeks   /bin/sh -c ...   31MB

docker history 是个被低估的命令——它能把镜像每一层是怎么来的(对应哪条 Dockerfile 指令、占了多大)列出来,优化镜像体积时全靠它。

6. docker inspect:看详细信息

# 查看镜像的详细信息

docker inspect nginx:1.25
# 返回一段很长的 JSON,包含:
#   - 架构(Architecture: amd64 / arm64)
#   - 操作系统(Os: linux)
#   - 暴露的端口(ExposedPorts)
#   - 环境变量(Env)
#   - 入口命令(Entrypoint / Cmd)
#   - 各层 SHA256

# 只看某个字段,用 -f 模板语法
docker inspect -f '{{.Architecture}}' nginx:1.25
docker inspect -f '{{.Config.ExposedPorts}}' nginx:1.25
docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' nginx:1.25

inspect 返回的 JSON 信息量很大,排查"这镜像到底配了什么环境变量""暴露了哪些端口"很有用。-f 模板语法用的是 Go template,语法是双花括号包裹(类似 {{}}),需要练习几次。

镜像分层原理(重要)

这是 Docker 镜像最核心的设计。一个镜像不是一整块文件,而是由多个只读层(layer)叠起来的,每层对应 Dockerfile 里的一条指令:

docker history 镜像名 能清楚看到每一层。优化镜像本质上就是减少层数、减少每层大小,后面 Dockerfile 和最佳实践章会展开。

镜像选型:alpine / slim / 默认

同一个应用通常有多个版本可选,怎么挑?

原则:生产 alpine,开发默认。如果 alpine 装某些包报错,改回 slim。

← 上一篇 Docker 环境安装

下一篇 Docker 容器

✈️💬