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 .