使用docker-java管理Docker时卷映射无法正常工作的问题排查
问题原因及解决方法
错误根源
你用错了docker-java中绑定挂载的API:
- 代码里直接把
宿主机路径:容器路径作为Volume的构造参数,这会导致Docker把整个字符串当成容器内的路径,而非解析成挂载映射。 - 实际容器里创建的是
/home/rick/temp/video_demo/input:/video_input这类异常目录,而非你期望的/video_input和/video_output,所以执行ls /video_output会提示找不到。
正确写法
需要用Bind类定义宿主机与容器的路径映射,再通过withBinds方法添加到容器配置中,而非直接用Volume和withVolumes。修改后的测试代码如下:
@Test public void testDockerVolumeMapping() throws Exception { DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder() .withDockerHost("unix:///var/run/docker.sock") .build(); DockerClient dockerClient = DockerClientBuilder.getInstance(config) .withDockerHttpClient(new ApacheDockerHttpClient.Builder().dockerHost(config.getDockerHost()).build()) .build(); String imageTag = "jrottenberg/ffmpeg:4.1-ubuntu"; dockerClient.pullImageCmd(imageTag).exec(new PullImageResultCallback()).awaitCompletion(5, TimeUnit.MINUTES); // 定义绑定挂载:宿主机路径 -> 容器内路径 Bind inputBind = Bind.bind("/home/rick/temp/video_demo/input", new Volume("/video_input")); Bind outputBind = Bind.bind("/home/rick/temp/video_demo/output", new Volume("/video_output")); String containerId = dockerClient.createContainerCmd(imageTag) .withBinds(inputBind, outputBind) // 使用withBinds添加挂载 .withEntrypoint("/bin/bash") .withCmd("-c", "ls /video_output") .withAttachStdout(true) .withAttachStderr(true) .exec().getId(); dockerClient.startContainerCmd(containerId).exec(); }
补充说明
Volume类仅用来表示容器内的路径,匿名卷或命名卷场景才会配合withVolumes使用;- 绑定挂载(对应
docker run -v的功能)必须用Bind类关联宿主机和容器路径,再通过withBinds方法传入配置。
内容的提问来源于stack exchange,提问作者babu babu
相关产品推荐
相关产品推荐

