docker-compose配置绑定挂载卷后数据未存入指定主机目录如何解决
排查解决步骤
1. 先确认当前容器实际的挂载状态,不要靠配置猜
不要默认改了docker-compose的配置就一定会生效,先逐个查正在运行的容器的真实挂载映射:
- 对每个运行的服务执行命令查看容器详情:
sudo docker inspect <对应容器的实际名称> - 在输出中找到
Mounts配置段,核对两个核心信息:- 宿主机的实际存储路径(Source字段)是不是你配置的自定义路径
- 容器内的目标路径(Destination字段)是不是你配置的路径
这里要特别注意:如果你修改过docker-compose.yml里的volumes配置,只执行docker-compose start是完全不会更新旧容器的挂载配置的——旧容器的所有配置(包括卷映射)是容器创建时就固定写入的,后续的start、restart操作都只会沿用旧配置,不会读取新的yml内容。
你之前观察到的“重启容器数据还在”,本质上是因为你没有删除过旧容器,数据一直存在容器自身的可写存储层里,根本不是Docker自动把数据存在了你配置的卷路径下。
2. 修正你配置里的核心路径错误
你现在写的所有容器内挂载路径,和对应服务实际的默认数据目录完全不匹配,这是数据根本不会写入自定义路径的核心原因:
- MSSQL 2019镜像:实际数据根目录是
/var/opt/mssql,你现在配置挂载的是/var/opt/sqlserver/data,这个路径MSSQL服务根本不会读写,所有真实数据全部存在容器内的/var/opt/mssql目录下,自然不会写到你自定义的宿主机路径里。你之前注释掉的那行/media/m/DataLinux/Code/Docker/db-playground/mssql:/var/opt/mssql才是正确的挂载路径。 - MongoDB 4.4镜像:官方镜像的默认数据目录是
/data/db,你现在配置挂载的是容器内的/var/data,这个路径Mongo服务完全不会使用,真实数据全部存在容器内的/data/db下,和你配置的卷完全脱节。 - postgres服务:你根本没有给这个服务配置任何卷挂载,所有数据直接存在容器可写层,本来就不会实现持久化。
3. 排查宿主机路径的权限问题
你用的宿主机路径是/media/下的独立挂载磁盘,Ubuntu默认对这类磁盘的权限控制比较严格,而容器内的服务大多是以非root用户身份运行的(比如MSSQL使用UID 10001的mssql用户,Mongo使用UID 999的mongodb用户):
- 如果宿主机上对应的自定义文件夹没有给对应用户的读写权限,就算路径挂载正确,服务也会因为没有写入权限,静默把数据写回容器的可写层,不会写入挂载的卷目录。
- 快速验证挂载连通性:可以在宿主机的自定义路径下创建一个测试文件,然后进入容器检查挂载的目标路径下能不能看到这个测试文件,如果看不到说明挂载本身就没有生效;如果能看到,再检查容器用户对这个路径的写入权限。
4. 修正后的参考配置
version: "3.7" services: sqlserver: image: mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04 ports: - "1433:1433" - "5022:5022" volumes: - /media/m/DataLinux/Code/Docker/db-playground/mssql:/var/opt/mssql environment: ACCEPT_EULA: Y SA_PASSWORD: Dev1234! mongo: image: amd64/mongo:4.4.3-bionic restart: always volumes: - /media/m/DataLinux/Code/Docker/db-playground/mongo-data:/data/db ports: - "27017:27017" environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: secret postgres: image: supabase/postgres:0.14.0 ports: - "5432:5432" volumes: - /media/m/DataLinux/Code/Docker/db-playground/postgres:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: postgres
改完配置后一定要执行sudo docker-compose down删除所有旧容器,再执行sudo docker-compose up -d重新启动服务,新的挂载配置才会生效。
内容的提问来源于stack exchange,提问作者Martin Andersen
相关产品推荐
相关产品推荐

