## 4.2 列出镜像

在下载了镜像后，我们可以使用 `docker image ls` 命令列出本地主机上的镜像。

### 4.2.1 基本用法

查看本地已下载的镜像：

```bash
$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
redis        latest    5f515359c7f8   5 days ago     183MB
nginx        latest    05a60462f8ba   5 days ago     181MB
ubuntu       24.04     329ed837d508   3 days ago     78MB
ubuntu       noble     329ed837d508   3 days ago     78MB
```
> 💡 `docker images` 是 `docker image ls` 的简写，两者等效。

---

### 4.2.2 输出字段说明

`docker image ls` 命令默认输出的列表包含仓库名、标签、镜像 ID、创建时间和占用空间等信息。

| 字段 | 说明 |
|------|------|
| **REPOSITORY** | 仓库名 |
| **TAG** | 标签 (版本)|
| **IMAGE ID** | 镜像唯一标识 (短 ID，前 12 位)|
| **CREATED** | 创建时间 |
| **SIZE** | 本地占用空间 |

#### 同一镜像多个标签

注意上面的 `ubuntu:24.04` 和 `ubuntu:noble` 拥有相同的 IMAGE ID——它们是同一个镜像的不同标签，只占用一份存储空间。

> **版本说明**：`ubuntu:24.04` 是具体版本号，`ubuntu:noble` 是发布代号（Ubuntu 24.04 的代号）。在 Dockerfile 中应优先使用版本号（如 `ubuntu:24.04`）而非发布代号，因为版本号在将来更易理解。

---

### 4.2.3 理解镜像大小

Docker 镜像的大小可能与我们通常理解的文件大小有所不同，这涉及到分层存储的概念。

#### 本地大小 vs Hub 显示大小

| 位置 | 显示大小 | 说明 |
|------|---------|------|
| Docker Hub | 29MB | 压缩后的网络传输大小 |
| docker image ls | 78MB | 本地解压后的实际大小 |

#### 实际磁盘占用

由于镜像是分层存储，不同镜像可能共享相同的层：

```bash
ubuntu:24.04    nginx:latest    redis:latest
    │               │                │
    └───────┬───────┘                │
            ▼                        │
       共享基础层 ◄───────────────────┘
```
因此，`docker image ls` 中各镜像大小之和 > 实际磁盘占用。

#### 查看实际空间占用

```bash
$ docker system df
TYPE            TOTAL   ACTIVE   SIZE      RECLAIMABLE
Images          15      3        2.5GB     1.8GB (72%)
Containers      5       2        100MB     80MB (80%)
Local Volumes   8       2        500MB     400MB (80%)
Build Cache     0       0        0B        0B
```
---

### 4.2.4 过滤镜像

随着本地镜像数量的增加，我们需要更有效的方式来查找特定的镜像。Docker 提供了多种过滤方式。

#### 按仓库名过滤

```bash
## 列出所有 ubuntu 镜像

$ docker images ubuntu
REPOSITORY   TAG     IMAGE ID       SIZE
ubuntu       24.04   329ed837d508   78MB
ubuntu       noble   329ed837d508   78MB
ubuntu       22.04   a1b2c3d4e5f6   72MB
```

#### 按仓库名和标签过滤

```bash
$ docker images ubuntu:24.04
REPOSITORY   TAG     IMAGE ID       SIZE
ubuntu       24.04   329ed837d508   78MB
```

#### 使用过滤器 --filter

| 过滤条件 | 说明 | 示例 |
|---------|------|------|
| `dangling=true` | 虚悬镜像 | `-f dangling=true` |
| `before=镜像` | 在某镜像之前创建 | `-f before=nginx:latest` |
| `since=镜像` | 在某镜像之后创建 | `-f since=nginx:latest` |
| `label=key=value` | 按 LABEL 过滤 | `-f label=version=1.0` |
| `reference=pattern` | 按名称模式 | `-f reference='*:latest'` |

```bash
## 列出 nginx 之后创建的镜像

$ docker images -f since=nginx:latest

## 列出所有带 latest 标签的镜像

$ docker images -f reference='*:latest'

## 列出带特定 LABEL 的镜像

$ docker images -f label=maintainer=example@email.com
```
---

### 4.2.5 虚悬镜像

在镜像列表里，你可能会看到一些仓库名和标签都为 `<none>` 的镜像，这类镜像被称为虚悬镜像。

#### 什么是虚悬镜像

仓库名和标签都显示为 `<none>` 的镜像：

```bash
$ docker images
REPOSITORY   TAG       IMAGE ID       SIZE
<none>       <none>    00285df0df87   342MB
```

#### 产生原因

1. **镜像重新构建**：新镜像使用了旧镜像的标签，旧镜像标签被移除
2. **docker pull 更新**：拉取更新版本时，旧版本失去标签

#### 处理虚悬镜像

```bash
## 列出虚悬镜像

$ docker images -f dangling=true

## 删除虚悬镜像

$ docker image prune
```
---

### 4.2.6 中间层镜像

除了虚悬镜像，`docker image ls` 默认列出的只是顶层镜像。还有一种镜像是为了加速镜像构建、重复利用资源而存在的中间层镜像。

#### 查看所有镜像：包含中间层

```bash
$ docker images -a
```
会显示很多无标签镜像——这些是构建过程中产生的中间层，被其他镜像依赖。

> ⚠️ 不要删除中间层镜像。它们是其他镜像的依赖，删除会导致上层镜像无法使用。删除顶层镜像时会自动清理不再需要的中间层。

---

### 4.2.7 格式化输出

为了配合脚本使用或展示更关注的信息，我们可以使用 `--format` 参数来自定义输出格式。

#### 只输出 ID

```bash
$ docker images -q
5f515359c7f8
05a60462f8ba
329ed837d508
```
常用于配合其他命令：

```bash
## 删除所有镜像

$ docker rmi $(docker images -q)

## 删除所有 redis 镜像

$ docker rmi $(docker images -q redis)
```

#### 显示完整 ID

```bash
$ docker images --no-trunc
```

#### 显示摘要

```bash
$ docker images --digests
REPOSITORY   TAG     DIGEST                    IMAGE ID
nginx        latest  sha256:b4f0e0bdeb5...    e43d811ce2f4
```

#### 自定义格式

使用 Go 模板语法自定义输出：

```bash
## 只显示 ID 和仓库名

$ docker images --format "{{.ID}}: {{.Repository}}"
5f515359c7f8: redis
05a60462f8ba: nginx
329ed837d508: ubuntu

## 表格形式（带标题）

$ docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
REPOSITORY   TAG       SIZE
redis        latest    183MB
nginx        latest    181MB
ubuntu       24.04     78MB
```

#### 可用模板字段

| 字段 | 说明 |
|------|------|
| `.ID` | 镜像 ID |
| `.Repository` | 仓库名 |
| `.Tag` | 标签 |
| `.Digest` | 摘要 |
| `.CreatedSince` | 创建后经过的时间 |
| `.CreatedAt` | 创建时间 |
| `.Size` | 大小 |

---

### 4.2.8 常用命令组合

```bash
## 列出所有镜像及其大小，按大小排序（需要系统 sort 命令）

$ docker images --format "{{.Size}}\t{{.Repository}}:{{.Tag}}" | sort -h

## 查找大于 500MB 的镜像

$ docker images --format "{{.Size}}\t{{.Repository}}:{{.Tag}}" | grep -E "^[0-9]+GB|^[5-9][0-9]{2}MB"

## 导出镜像列表

$ docker images --format "{{.Repository}}:{{.Tag}}" > images.txt
```
---
