fussybeaver / bollard

Docker daemon API in Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bind Volume Mounts

pedrobmorales opened this issue · comments

I'm trying to mount a volume in my container as if I did -v argument to docker container run.
I am not sure how to use the volumes field of bollard::container::Config.

Basically I want to

docker container run -v $(pwd)/my/folder:/etc/myapp/config my_image arg1 arg2 arg3

This is what I'm trying:

   let mut volume_mounts = HashMap::new();
    let empty_map = HashMap::new();
    // empty_map.insert((), ());
    volume_mounts.insert(config_yaml_mount.as_str(), empty_map);

    let create_container_options = bollard::container::Config {
        image: Some(config.ninja_panda_image.as_str()),
        env: Some(vec![
            ninja_db_host.as_str(),
            ninja_db_pass.as_str(),
            ninja_db_name.as_str(),
        ]),
        volumes: Some(volume_mounts),
        ..Default::default()
    };
    let container = docker
        .create_container(
            Some(bollard::container::CreateContainerOptions {
                platform: Some("linux/arm64"),
                name: container_name,
            }),
            create_container_options,
        )
        .await?;

Could you try something like this?

    let mut binds = vec![];
    binds.push(format!(
        "{}:{}",
        "/my/folder".to_owned(),
        "/etc/myapp/config".to_owned()
    ));

    let create_container_options = bollard::container::Config {
        image: Some(config.ninja_panda_image.as_str()),
        env: Some(vec![
            ninja_db_host.as_str(),
            ninja_db_pass.as_str(),
            ninja_db_name.as_str(),
        ]),
        binds: Some(binds),
        ..Default::default()
    };
    let container = docker
        .create_container(
            Some(bollard::container::CreateContainerOptions {
                platform: Some("linux/arm64"),
                name: container_name,
            }),
            create_container_options,
        )
        .await?;

Hi, it did not work, there is a compiler error because binds is a Vector but the library requires a HashMap.

I'd be happy to try to submit a PR. I think in general the typing of the volume mount:

HashMap<&str, HashMap<(),()>

Should be clarified a bit. Perhaps to

HashMap<&str, Vector<VolumeMountOption>

Where VolumeMountOption is perhaps an enum of the mount point commands supported by Docker.

When I run my command on the cli, with docker I get the correct behavior:

docker container run -it -v $(pwd):/home/np  31c701dbd122 sh
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/Users/pmorales/Git/ninja-panda",
                "Destination": "/home/np",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

I think your library is excellent by the way. I can attempt to provide a patch for the capability, I think it just didn't get implemented.

Try this instead:

let mut binds = vec![];
    binds.push(format!(
        "{}:{}",
        "/my/folder",
        "/etc/myapp/config"
    ));

    let create_container_options = bollard::container::Config {
        image: Some(config.ninja_panda_image.as_str()),
        env: Some(vec![
            ninja_db_host.as_str(),
            ninja_db_pass.as_str(),
            ninja_db_name.as_str(),
        ]),
        binds: Some(binds),
        ..Default::default()
    };

This will work when you get the types right, I usually use String everywhere, but you want to go for str instead.
This is a vector, not a hashmap: https://docs.rs/bollard/0.13.0/bollard/models/struct.HostConfig.html#structfield.binds

Hi, you are correct, this worked!!

    let path_mount = format!(
        "{}:{}",
        "/Users/pmorales/Git/dockertest/conf/ninjapanda".to_owned(),
        "/home/ninjapanda".to_owned()
    );

    let create_container_options = bollard::container::Config {
        image: Some(config.ninja_panda_image.as_str()),
        env: Some(vec![
            ninja_db_host.as_str(),
            ninja_db_pass.as_str(),
            ninja_db_name.as_str(),
        ]),
        host_config: Some(HostConfig {
            binds: Some(vec![path_mount]),
            ..Default::default()
        }),
        ..Default::default()
    };

I was confused by container::Config::volumes but I really needed container::Config::host_config::binds.

Thank you for your help!