镜像、容器和数据卷协同实现应用可复现与数据持久化:镜像为只读模板不存业务数据,容器是其运行实例并依赖数据卷持久化数据,数据卷独立于镜像和容器生命周期,支持升级、重建与共享。
镜像、容器和数据卷是 docker 中三个相互依赖的核心组件,它们配合使用才能让应用既可复现又不丢数据。
镜像提供运行环境,但本身不存业务数据
镜像是一套只读的模板,包含操作系统、MySQL 二进制文件、默认配置等。它不保存任何实际数据——比如你往 MySQL 里插入的记录,不会写进镜像里。就像一份安装包,装完系统后,你写的文档不会反向改安装包本身。
所以直接用 docker run mysql:8.0 启动容器,所有数据都存在容器的可写层里。一旦执行 docker rm -f,数据就彻底没了。
容器是镜像的运行实例,靠挂载数据卷来“留住数据”
容器启动时,Docker 会在镜像的只读层上叠加一个可写层。这个可写层默认是临时的。要让它持久,就得把关键路径(如 MySQL 的 /var/lib/mysql)指向外部存储,也就是数据卷。
- 用命名卷:启动时加
-v my-mysql-data:/var/lib/mysql,Docker 自动在/var/lib/docker/volumes/下建目录并管理 - 用绑定挂载:启动时加
-v /home/data/mysql:/var/lib/mysql,数据直接落在你指定的宿主机路径 - 两种方式都会让 MySQL 进程把数据写进挂载点,而不是容器内部的临时层
数据卷独立于镜像和容器生命周期
镜像可以更新(比如从 mysql:8.0.31 升级到 mysql:8.0.33),容器可以删了重建,但只要挂载的是同一个数据卷,MySQL 就能接着用原来的数据目录启动。
例如:
- 先运行:
docker run -d --name db1 -v mydata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 mysql:8.0.31 - 插入几条测试数据
- 停掉并删除容器:
docker stop db1 && docker rm db1 - 换新镜像再起:
docker run -d --name db2 -v mydata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 mysql:8.0.33 - 连上去查,数据还在——因为真正存数据的地方(
mydata卷)根本没动过
实际部署中三者分工明确
镜像负责定义“怎么跑”,容器负责“正在跑”,数据卷负责“数据在哪”。这种分离让运维更可控:升级镜像不用迁移数据,重装系统只需备份卷目录,多个容器还能共享同一份数据(比如主从同步场景下共用 binlog 卷)。











