Docker容器未挂载卷时数据不持久,删容器即丢失;验证需执行“建表→删容器→重跑→查数据”闭环,重点检查挂载配置、宿主机目录权限及YAML格式是否正确。

docker run 启动时没挂 -v,数据肯定不持久
容器一删,里面所有文件就清空,这是 Docker 可写层的默认行为。Oracle XE 11g 的数据默认落在 /u01/app/oracle/oradata,SQL Server 2022 落在 /var/opt/mssql/data,Redis 默认在 /data——这些路径如果没被 -v 或 --mount 显式挂载,就全在容器可写层里,重启都可能丢,更别说重建了。
验证前先确认启动命令里有没有挂载项:
- 查正在运行的容器:运行
docker inspect,搜"Mounts"字段,看是否有非空数组 - 查历史命令:如果用的是脚本或 compose,翻出启动命令,确认包含类似
-v oracle-data:/u01/app/oracle/oradata或-v /host/path:/data的挂载 - 没挂载?那后续所有“验证”都是徒劳,先补上再测
建表 → 重启容器 → 查数据,是最简验证链路
别信“容器没退出所以数据还在”,要模拟真实重建场景。关键不是“重启”,而是“删掉再起一个同名新容器”,才能暴露持久化是否真生效。
以 Oracle XE 11g 为例(其他数据库逻辑一致):
- 进容器执行 SQL:
sqlplus / as sysdba,然后建个测试表:CREATE TABLE test_persist (id NUMBER); INSERT INTO test_persist VALUES (1); COMMIT; - 停并删容器:
docker stop oracle-xe && docker rm oracle-xe - 用**完全相同的命令**重新启动(含相同卷名、相同挂载路径、相同环境变量):
docker run -d -v oracle-data:/u01/app/oracle/oradata -p 1521:1521 --name oracle-xe oracleinanutshell/oracle-xe-11g - 等容器 ready 后再次连库:
SELECT COUNT(*) FROM test_persist;—— 如果返回1,说明数据还在;如果报ORA-00942: table or view does not exist,就是挂载失败或路径不对
docker volume inspect 要看宿主机真实路径和权限
卷创建成功 ≠ 挂载成功 ≠ 数据能写入。常见卡点是权限:Oracle 镜像里 oracle 用户 UID 是 54321,但宿主机对应目录可能是 root 或普通用户所有,导致容器启动后无法写入数据文件,日志里会反复报 Permission denied 或直接静默失败。
必须手动验证卷的宿主机落地状态:
- 查卷位置:
docker volume inspect oracle-data,记下Mountpoint字段值,比如/var/lib/docker/volumes/oracle-data/_data - 进宿主机该目录:
ls -l /var/lib/docker/volumes/oracle-data/_data,确认子目录XE(Oracle XE 实例名)存在,且属主是54321或oracle - 如果不是,得提前改权限:
sudo chown -R 54321:54321 /var/lib/docker/volumes/oracle-data/_data(注意:Docker Desktop for Mac/Windows 的卷路径不在本地磁盘,这步只适用于 Linux 宿主机)
docker-compose.yml 里 volumes 键值对容易漏写冒号
YAML 对格式极其敏感,volumes 下写错一个字符,Docker 就当没挂载。最常踩的坑是把命名卷写成字符串而非映射对:
# ❌ 错误:这行会被忽略,实际没挂载 volumes: - oracle-data:/u01/app/oracle/oradata <h1>✅ 正确:必须用冒号分隔,且前后无空格</h1><p>volumes:</p><ul><li>oracle-data:/u01/app/oracle/oradata
另一个典型错误是路径写反了:- /host/path:/container/path 是 bind mount,而 - named-volume:/container/path 才是 volume。混用会导致数据落错地方,重建后查不到。
验证方法很简单:启动后立刻进容器,ls -l /u01/app/oracle/oradata,如果看到的是空目录或只有 lost+found,基本就是挂载失败;如果能看到 XE 目录及里面一堆 .dbf 文件,才说明挂对了。
真正麻烦的不是命令写不对,而是挂载看似成功、容器也正常启动、连库也通,但第一次写入就失败——这种静默故障,往往要等到你删容器重跑才发现数据没了。所以每次部署新数据库容器,务必走一遍“建表→删容器→重跑→查数据”的闭环,别跳过。


















