根本原因是容器可写层随容器删除而消失,数据未持久化;三种可靠方式为:命名卷(docker管理、独立生命周期)、绑定挂载(宿主机目录直连,需注意路径权限)、tmpfs(内存临时存储,停机即清)。
镜像和容器不是同一类东西:镜像是只读的静态模板,容器是它的运行实例。容器启动时,docker 会在镜像层之上加一层可读写层,所有你在容器里改的文件、存的数据,都落在这一层。但这一层和容器绑定——容器删了,这层就没了,数据自然消失。
为什么删容器就丢数据?
根本原因在于默认存储机制没做持久化。你往 /var/lib/mysql 写数据库文件,如果没挂卷,实际写进的是容器自己的可写层;一旦执行 docker rm,这层被清空,连带所有数据一并清除。
三种可靠的数据持久化方式
命名卷(Volume)——生产环境首选
由 Docker 管理,独立于容器生命周期,支持备份、迁移和插件扩展。
操作示例:
- 创建卷:
docker volume create mysql-data - 挂载启动:
docker run -d -v mysql-data:/var/lib/mysql mysql:8.0 - 删掉容器再重建,只要还挂这个
mysql-data,数据就原样保留
绑定挂载(Bind Mount)——适合配置与开发
把宿主机目录直接映射进容器,修改实时可见,但要注意路径和权限。
关键点:
- 路径必须对准容器内服务默认数据目录(如 PostgreSQL 必须是
/var/lib/postgresql/data) - 宿主机目录属主和权限要匹配容器内用户(例如 UID=999 的 postgres 用户需有写权限)
- 避免用相对路径(如
./data),跨机器部署易失效
tmpfs 挂载——只用于临时敏感数据
数据存在内存中,容器停止即清空,不落盘,适合 session、token 等无需留存的内容。
命令示例:docker run --tmpfs /run/secrets:rw,noexec,nosuid,size=64k nginx
验证数据是否真正持久化
别只看“能启动”,要实测三步:
- 启动容器并写入测试数据(比如在 MySQL 里建个表、插条记录)
- 执行
docker stop && docker rm删除容器,但不删卷 - 用相同卷重新运行容器,进入检查原数据是否存在(如
docker exec mydb ls /var/lib/mysql)
只有通过这三步,才算真正落地了持久化。











