Docker 里最核心的 4 个对象你先把这 4 个概念分清:
-
镜像 image
-
容器 container
-
镜像层 layer
-
仓库 registry/repository
1. 镜像是什么
镜像可以理解成:
一个只读的运行模板
它里面包含:
-
操作系统基础环境
-
Python
-
你的依赖包
-
你的项目代码
-
容器启动命令
例如:
python:3.11-slim
它是一个基础镜像。 而你后面构建出来的:
resume-assistant:latest
是一个业务镜像。
镜像本身不会"运行",它只是一个模板。
2. 容器是什么
容器可以理解成:
镜像运行起来之后的实例
比如:
docker run resume-assistant:latest
这时 Docker 会基于镜像创建一个容器。
所以关系是:
镜像 -> 启动 -> 容器
就像:
-
类 -> 实例
-
模板 -> 实际运行对象
一个镜像可以启动多个容器。
3. 镜像层是什么
这是你刚才问题的关键。
Docker 镜像不是一个"大文件硬拷贝",而是由多层组成的。
例如你的项目镜像可能逻辑上长这样:
第1层:Linux 基础系统层 第2层:Python 3.11 层 第3层:pip 安装 requirements.txt 的依赖层 第4层:复制 app/ 代码层 第5层:启动命令和环境变量层
这些层会被缓存和复用。
为什么这很重要
假设你已经有:
python-base:3.11-slim
然后构建 resume-assistant:latest 时,是在这个基础上往上叠新层。
所以:
-
不会把底层完整重复复制一份
-
多个镜像可以共享同样的基础层
这就是为什么"拉一个基础镜像"不等于浪费一整份重复空间。
4. 仓库是什么
仓库就是存放镜像的地方。
比如:
-
Docker Hub
-
阿里云 ACR
你这次做的事情就是把基础镜像从 Docker Hub 迁移到阿里云 ACR,方便服务器拉取。
例如:
crpi-.../sunxuehai/python-base:3.11-slim
这里:
-
crpi-... 是 registry 域名
-
sunxuehai/python-base 是仓库路径
-
3.11-slim 是 tag
刚才发生的事情,按原理拆开
你刚才在服务器执行了:
docker pull crpi-.../sunxuehai/python-base:3.11-slim
它做的事情不是"把一个文件下载到当前目录",而是:
-
Docker 去远程仓库找到这个镜像
-
把镜像的各层下载到本机 Docker 存储
-
在本机镜像列表中注册这个镜像 tag
-
后续 build/run 时可以直接复用
所以它更像是:
"导入到 Docker 本地镜像缓存" 而不是 "下载一个独立压缩包到你的 home 目录"
为什么以后不需要每次都重新拉
因为 Docker 会先看本地有没有这个镜像层。
如果你已经拉过:
python-base:3.11-slim
那以后再 build:
-
只要基础镜像没变
-
本地缓存还在
Docker 通常直接复用,不重新下载。
这就是缓存机制。
那 Docker 为什么有时候又会重新拉
因为以下几种情况会触发重新拉:
-
本地没有这个镜像
-
你手动删掉了它
-
你换了 tag
-
远程镜像更新而你要求刷新
-
构建环境不是同一台机器
所以"是否重新拉"取决于:
-
本地缓存是否存在
-
镜像标识是否一致
-
你有没有主动刷新
为什么镜像和容器都会占空间
这是新手最容易混的地方。
镜像占空间
因为镜像层要存储:
-
Python
-
系统层
-
pip 包
-
代码
容器也占空间
因为容器运行后会产生:
-
可写层
-
日志
-
临时数据
所以后面磁盘管理一般要区分:
-
镜像占多少
-
容器占多少
-
volume 占多少
-
build cache 占多少
你接下来最应该建立的意识
Docker 不是"每次执行一条命令就产生一个没法控制的大黑盒",而是一个有状态的本地系统:
-
pull 是把镜像放进本地镜像缓存
-
build 是基于已有层构造新镜像
-
run 是基于镜像创建容器
-
push 是把镜像上传到远程仓库
-
rm/rmi/prune 是清理本地状态
对你当前项目,这个理解具体落到什么地方
现在服务器上已经有一个基础镜像:
crpi-.../sunxuehai/python-base:3.11-slim
接下来如果我们 build 项目镜像:
resume-assistant:latest
它不会从零开始,而是:
-
以 python-base:3.11-slim 为底座
-
再安装 requirements
-
再复制项目代码
-
生成新的业务镜像
所以基础镜像不是垃圾,而是后续构建的"底座缓存"。