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 ... 31MBdocker 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.25inspect 返回的 JSON 信息量很大,排查"这镜像到底配了什么环境变量""暴露了哪些端口"很有用。-f 模板语法用的是 Go template,语法是双花括号包裹(类似 {{}}),需要练习几次。
镜像分层原理(重要)
这是 Docker 镜像最核心的设计。一个镜像不是一整块文件,而是由多个只读层(layer)叠起来的,每层对应 Dockerfile 里的一条指令:
- 分层共享:多个镜像共享同一层时,本地只存一份。
ubuntu:22.04这一层,你拉了 5 个基于它的镜像也只占一次空间。 - 分层缓存:构建时,某层指令没变就直接复用缓存,加速构建。这就是为什么 Dockerfile 里"不变的指令放前面"。
- 写时复制:容器启动时,在镜像顶层加一个可写层。容器修改文件时,Docker 才把那一份复制到可写层,底层镜像不受影响。
用 docker history 镜像名 能清楚看到每一层。优化镜像本质上就是减少层数、减少每层大小,后面 Dockerfile 和最佳实践章会展开。
镜像选型:alpine / slim / 默认
同一个应用通常有多个版本可选,怎么挑?
- alpine:基于 Alpine Linux,5MB 级别,极致精简。生产首选,但基于 musl libc,极少数 C 扩展可能装不上。
- slim:基于 Debian,删掉不必要文档和工具,几十到一百多 MB。兼容性比 alpine 好。
- 默认(如
node:20):完整 Debian,几百 MB 到 1GB,装了完整编译工具链。开发环境方便,生产不推荐。 - bullseye/jammy:指定 Debian/Ubuntu 版本代号,锁定基础系统。
原则:生产 alpine,开发默认。如果 alpine 装某些包报错,改回 slim。
← 上一篇 Docker 环境安装
下一篇 Docker 容器 →