docker inspect --format '{{.Mounts}}' 无法直接获取 HostPath,因为 .Mounts 是 slice 类型,Go 模板不支持自动展开嵌套字段;需用 {{json .Mounts}} 输出结构化 JSON,再通过 jq 提取 .Source 字段——bind 类型对应真实宿主机路径,volume 类型则为 Docker 内部路径。

docker inspect --format 为什么取不到 HostPath
直接用 docker inspect --format '{{.Mounts}}' container_name 只会输出一串 Go 模板结构体文本,比如 [{volume local /var/lib/docker/volumes/xxx/_data /mnt/data local true }] ,根本没法直接拿到宿主机路径。这是因为 .Mounts 是个 slice,Go 模板不支持直接索引或展开嵌套字段——你得手动遍历或换用 json 解析。
用 jsonpath 提取 HostPath 最可靠
真正能稳定提取宿主机路径的是 docker inspect -f '{{json .Mounts}}' container_name 配合 jq,而不是纯 --format。原因:只有 json 输出才能被结构化解析,.Mounts 中每个元素的 Source 字段才是你要的物理路径(对 bind mount)或 volume 数据目录(对 named volume)。
- 对 bind mount 容器:
docker inspect -f '{{json .Mounts}}' myapp | jq -r '.[] | select(.Type=="bind") | .Source' - 对 named volume 容器:
docker inspect -f '{{json .Mounts}}' myapp | jq -r '.[] | select(.Type=="volume") | .Source' - 如果容器有多个挂载,且你只认准某条
Destination(如/data),加条件:select(.Destination=="/data")
注意 Source 字段在不同挂载类型下的真实含义
.Source 看起来是“宿主机路径”,但实际取决于挂载类型,容易误判:
-
Type: "bind"→.Source就是真实绝对路径,比如/home/user/mydata -
Type: "volume"→.Source是 Docker 管理的内部路径,例如/var/lib/docker/volumes/myvol/_data,不是你docker volume create时指定的路径(它没这个概念) -
Type: "tmpfs"→.Source为空,别白费劲
如果你用的是 docker run -v /host/path:/cont/path,那一定是 bind 类型;如果是 -v myvol:/cont/path,那就是 volume 类型,.Source 指向的是 Docker daemon 自己的存储位置,不能直接当成用户定义路径。
不用 jq 的纯 shell 替代方案(仅限简单场景)
如果目标环境没装 jq,又确定只有一个 bind 挂载,可以用 docker inspect + grep + awk 快速捞,但非常脆弱:
docker inspect container_name | grep -A 10 '"Type": "bind"' | grep '"Source":' | awk -F': ' '{print $2}' | tr -d '", '
这种写法依赖 JSON 格式缩进和字段顺序,Docker 版本一升级、字段换行一变就失效。生产脚本里别这么干;临时调试凑合用可以,但得清楚它随时会崩。
真正要稳,还是得靠 json + jq。Volume 路径本身不加密也不隐藏,但 Docker 不提供“用户原始输入路径”的元数据字段——.Source 就是最终落盘地址,接受它,比试图反推更实际。











