Docker 容器退出后数据会丢失吗
FreeGuideOnline
最新
2026-07-05
bash
1. 创建一个具名数据卷 my_volume
docker volume create my_volume
2. 启动容器并将数据卷挂载到容器内的 /app/data 目录
docker run -d --name my_container -v my_volume:/app/data nginx
现在在容器内 /app/data 写入的任何文件,都会保存到数据卷中。
即使停止并删除 my_container,数据卷依然存在。
3. 查看数据卷
docker volume ls
4. 再次启动一个新容器,挂载同一个数据卷,数据完好无损
docker run -d --name new_container -v my_volume:/app/data nginx
5. 不再需要时,可以删除数据卷(确保无容器使用)
docker volume rm my_volume
如果使用 `-v` 时不指定宿主机路径而只给一个名称,Docker 会自动创建该名称的数据卷。
#### 方案二:使用绑定挂载(Bind Mounts)
绑定挂载可以将宿主机上的**任意指定目录或文件**直接映射到容器内部。这种方式依赖宿主机的文件系统结构,更加透明,但可移植性稍差。
- **优点**:可以直接在宿主机上用熟悉的工具编辑文件,方便开发调试。
- **操作示例**:
```bash
# 假设你有一个宿主机目录 /host/data 想要分享给容器
mkdir -p /host/data
# 将该目录挂载到容器内的 /container/data
docker run -d --name my_container -v /host/data:/container/data nginx
# 在宿主机 /host/data 中创建文件 test.txt
echo "Hello from host" > /host/data/test.txt
# 进入容器查看,文件已存在
docker exec my_container cat /container/data/test.txt # 输出: Hello from host
注意:绑定挂载的宿主机路径必须使用绝对路径,或者使用 $(pwd) 等当前目录变量。
数据卷 vs 绑定挂载:一张表看懂区别
| 特性 | 数据卷 (Volume) | 绑定挂载 (Bind Mount) |
|---|---|---|
| 管理者 | 由 Docker 完全管理,存储在 Docker 区域 | 由用户手动管理,可位于宿主机任意位置 |
| 可移植性 | 易于在不同操作系统和 Docker 环境间迁移 | 强依赖于宿主机目录结构,移植性差 |
| 与容器耦合度 | 低,通过名字引用,容器删除后卷仍在 | 中等,直接绑定宿主机路径 |
| 多容器共享 | 非常方便 | 方便,但需注意权限问题 |
| 典型场景 | 生产环境数据库、应用状态存储 | 开发时挂载源代码、配置文件实时生效 |
| 性能 | 通常性能较好(针对 Docker 存储驱动优化) | 性能取决于宿主机文件系统,可能略优(特定场景) |
常见场景实战:让数据不再丢失
场景一:运行一个数据持久的 MySQL 容器
# 创建一个数据卷专门存放 mysql 数据
docker volume create mysql_data
# 启动 MySQL 容器,将数据目录挂载出来
docker run -d \
--name mysql_db \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-v mysql_data:/var/lib/mysql \
mysql:8.0
# 此时,数据库的所有表结构、记录都存储在 mysql_data 卷中。
# 即使删除容器 `docker rm -f mysql_db`,数据依然安全。
# 再次启动一个新容器挂载相同卷,数据库即可恢复。
场景二:开发中实时更新代码(使用绑定挂载)
# 假设你的前端项目代码在 ~/myapp 目录
docker run -d \
--name dev_app \
-p 3000:3000 \
-v ~/myapp:/usr/src/app \
node:18-alpine sh -c "npm install && npm start"
# 现在你在宿主机 ~/myapp 中修改代码,容器内的应用会自动检测变化并重启,无需重建镜像。
注意事项与最佳实践
- 不要混淆匿名卷:如果你在 Dockerfile 中用
VOLUME指令声明,但未指定挂载,Docker 会为容器自动创建一个匿名卷。容器删除时,匿名卷默认不会被删除,除非使用docker rm -v。这容易导致未使用的卷占用磁盘空间,建议显式管理具名卷或绑定点。 - 权限问题:挂载后容器中的用户(如 node、www-data)可能没有权限读写挂载目录。可以通过在 Dockerfile 中指定正确用户,或在宿主机上调整目录权限(如
chown 1000:1000)来解决。 - 数据备份:对于数据卷,可以使用临时容器执行备份命令:
docker run --rm -v my_volume:/source -v $(pwd):/backup alpine tar cvf /backup/backup.tar -C /source .