第七篇:《Docker 存储:Volume、Bind Mount 与 tmpfs》

发布时间:2026/5/28 15:40:40

第七篇:《Docker 存储:Volume、Bind Mount 与 tmpfs》 容器默认的文件系统是临时的——容器删除后其中所有数据都会丢失。对于数据库、日志、配置等需要持久化的数据Docker 提供了三种存储方式Volume、Bind Mount 和 tmpfs。本文将详细讲解三者的原理、适用场景以及具体操作方法帮助你正确管理容器数据。一、容器存储的临时性问题Docker 容器的可写层与容器生命周期绑定容器运行时所有对文件系统的修改都写入容器的可写层位于宿主机 /var/lib/docker/overlay2/…。容器被删除时可写层随之删除数据永久丢失。即使使用 docker commit 将容器保存为新镜像也只能保留当时的状态不适合频繁变化的数据。因此需要独立于容器生命周期的存储方案。二、Docker 的三种存储挂载类型三、Volume卷Volume 是 Docker 推荐的持久化方式由 Docker 完全管理独立于容器。3.1 基本操作# 创建卷dockervolume create mydata# 列出卷dockervolumels# 查看卷详情dockervolume inspect mydata# 删除卷只有未被任何容器使用才能删除dockervolumermmydata# 删除所有未使用的卷dockervolume prune3.2 使用卷挂载容器# 运行容器时挂载卷如果卷不存在会自动创建dockerrun-d--namedb-vmydata:/var/lib/mysql mysql# 使用 --mount 语法更显式dockerrun-d--namedb--mountsourcemydata,target/var/lib/mysql mysql# 只读挂载dockerrun-d--nameweb--mountsourceconfig,target/etc/nginx/conf.d,readonly nginx3.3 卷的备份与恢复# 备份启动一个临时容器挂载源卷和目标目录打包dockerrun--rm-vmydata:/source-v$(pwd):/backup alpinetarczf /backup/mydata-backup.tar.gz-C/source.# 恢复创建一个新卷解压备份文件dockervolume create newdatadockerrun--rm-vnewdata:/target-v$(pwd):/backup alpinetarxzf /backup/mydata-backup.tar.gz-C/target3.4 适用场景数据库MySQL、PostgreSQL、MongoDB的数据目录。应用需要持久化的用户上传文件、日志文件。需要在多个容器之间共享数据例如一个卷挂载到多个容器。四、Bind Mount绑定挂载Bind Mount 将宿主机上的任意目录或文件挂载到容器中。它依赖宿主机文件系统结构因此可移植性较差但在开发环境中非常方便。4.1 基本用法# 将当前目录挂载到容器的 /appdockerrun-d--namedev-v$(pwd):/app node:18# 使用 --mount 语法推荐dockerrun-d--namedev--mounttypebind,source$(pwd),target/app node:18# 只读绑定dockerrun-d--namedev--mounttypebind,source$(pwd),target/app,readonly node:184.2 开发环境典型用法在开发 Web 应用时将代码目录挂载到容器内修改代码后容器内立即生效无需重建镜像# 项目结构./myapp/ ├── index.html ├── app.js └── Dockerfile# 启动容器挂载代码目录dockerrun-d-p3000:3000-v$(pwd):/app node:18npmstart4.3 注意事项路径必须使用绝对路径$(pwd) 或完整路径。文件权限容器内进程的用户 ID 可能与宿主机不同可能导致权限错误。可以通过 --user 或调整宿主机文件权限解决。性能Bind Mount 在 macOS/Windows 下通过文件共享机制如 VirtioFS、gRPC FUSE可能比 Volume 慢但对开发来说影响不大。五、tmpfs 挂载tmpfs 将数据存储在内存中不写入磁盘。容器停止或删除后tmpfs 中的数据会丢失。5.1 基本用法# 挂载 tmpfs 到容器的 /tmpdockerrun-d--nametemp--tmpfs/tmp:rw,noexec,nosuid,size100m alpine# 使用 --mount 语法仅 Linuxdockerrun-d--nametemp--mounttypetmpfs,destination/tmp,tmpfs-size100m alpine5.2 适用场景存放临时敏感数据如 session、密码避免写入磁盘。提高频繁读写临时文件的性能如编译缓存。测试环境中需要隔离文件系统但又不想持久化。六、三种方式对比与选择选择建议生产环境持久化数据 → Volume开发环境代码热加载 → Bind Mount临时敏感数据或缓存 → tmpfs七、实战MySQL 数据持久化与备份恢复# 1. 创建数据卷dockervolume create mysql-data# 2. 启动 MySQL 容器dockerrun-d--namemysql\-vmysql-data:/var/lib/mysql\-eMYSQL_ROOT_PASSWORDroot\mysql:8.0# 3. 插入测试数据dockerexec-imysql mysql-uroot-prootEOF CREATE DATABASE test; USE test; CREATE TABLE t(id INT); INSERT INTO t VALUES(1); EOF# 4. 备份卷数据dockerrun--rm-vmysql-data:/source-v$(pwd):/backup alpine\tarczf /backup/mysql-backup.tar.gz-C/source.# 5. 删除原容器和卷模拟灾难dockerstop mysqldockerrmmysqldockervolumermmysql-data# 6. 创建新卷并恢复dockervolume create mysql-data-newdockerrun--rm-vmysql-data-new:/target-v$(pwd):/backup alpine\tarxzf /backup/mysql-backup.tar.gz-C/target# 7. 启动新容器验证数据dockerrun-d--namemysql-new-vmysql-data-new:/var/lib/mysql mysql:8.0dockerexec-itmysql-new mysql-uroot-proot-eSELECT * FROM test.t八、常见问题与解决九、小结本文详细介绍了 Docker 的三种存储方式。Volume 是生产环境持久化的首选Bind Mount 适合开发调试tmpfs 用于临时内存数据。理解它们的特性和适用场景能够帮助你设计出数据可靠、易于管理的容器化应用。

相关新闻