javadockerdocker-java

Manage docker with docker-java, the volume mapping seems not working


Environment: Fedora 39 openjdk-17 docker 25.01

My purpose is to run ffmpeg to merge Multiple video files into a single file, and i choose to use docker(manage by com.github.docker-java:docker-java:3.3.4) to do that.

But i encountered a problem: i declared two volume mappings and bind them to container, and then start the container immediately, the mapping directories seems not exist in container.

Here is a springboot test case below:

@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);
        Volume inputVM = new Volume("/home/rick/temp/video_demo/input:/video_input");
        Volume outputVM = new Volume("/home/rick/temp/video_demo/output:/video_output");
        String containerId = dockerClient.createContainerCmd(imageTag)
                .withVolumes(inputVM, outputVM)
                .withEntrypoint("/bin/bash")
                .withCmd("-c", "ls /video_output")
                .withAttachStdout(true)
                .withAttachStderr(true)
                .exec().getId();
        dockerClient.startContainerCmd(containerId).exec();
    }

run docker command:

docker logs ${containerId}

there is an error message:

ls: cannot access '/video_output': No such file or directory

start the container again with command:

docker start ${containerId}
docker logs ${containerId}

and there is one more error message, the content is the same as last one.

But when i use docker run command:

docker run -v /home/rick/temp/video_demo/input:/video_input -v /home/rick/temp/video_demo/output:/video_output --entrypoint "/bin/bash" jrottenberg/ffmpeg:4.1-ubuntu -c "ls /video_output"

the directory content show correctly.

What is the reason?


Solution

  • I think you have to create a Bind for the volume.

    Volume inputVM = new Volume("/home/rick/temp/video_demo/input");
    Bind bindInput = new Bind("video_input", inputVM);
    
    String containerId = dockerClient.createContainerCmd(imageTag)
            .withVolumes(inputVM, outputVM)
            .withBinds(bindInput)
            .withEntrypoint("/bin/bash")
            .withCmd("-c", "ls /video_output")
            .withAttachStdout(true)
            .withAttachStderr(true)
            .exec().getId();
    

    Not sure if you have to add the volumes separatly