14

I am currently trying to create a Docker container using the official GoLang Docker SDK and am trying to mount a volume from my localhost to the docker container.

vol := map[string]struct{}{"/pathInDocker":{}}

// This was prepared using example at:
//https://docs.docker.com/develop/sdk/examples/#run-a-container
res, err := cli.ContainerCreate(ctx, &container.Config{
    Image: testImageName,
    Volumes: vol,
    Cmd: []string{"ls", "/"},
}, nil, nil, "")

This works at creating the container and adding the "/pathInDocker" to the docker container, however, I cannot figure out how to add the mount point for the localhost.

I have tried the following possible values for the vol variable

vol := map[string]struct{}{"localPath:/pathInDocker":{}}
vol := map[string]struct{}{"\"localPath\":\"/pathInDocker\"":{}}

And for each of these the resulting docker container attempts to mount the map key as the folder in docker with not mount point for localhost.

I've dug through the docs and the only line I can seem to find talking about how to configure volumes at all is this one:

Volumes         map[string]struct{} // List of volumes (mounts) used for the container

So my question is how to configure this so it mounts a local folder to the volume?

Shahriar
  • 13,460
  • 8
  • 78
  • 95
Dragonman117
  • 478
  • 4
  • 13

2 Answers2

33

If you want to use bind mounts, you need to provide your mount information in HostConfig.

res, err := client.ContainerCreate(
    ctx,
    &container.Config{
        Image: "nginx",
        Cmd:   []string{"ls", "/"},
    },
    &container.HostConfig{
        Mounts: []mount.Mount{
            {
                Type:   mount.TypeBind,
                Source: "/localPath",
                Target: "/pathInDocker",
            },
        },
    },
    nil,
    "",
)

And if you want to use volume, 1st you need to create a volume with mount path, then you need to use this volume name as Source.

Shahriar
  • 13,460
  • 8
  • 78
  • 95
  • This is great answer for bind mounts, which does answer the original question. But what to about a normal volume such as `-v data:/var/www/html`? – jmvbxx May 13 '18 at 00:39
  • 5
    I was able to mount a docker volume in by creating it first with `VolumeCreate` and then using the name of my volume in the mount array like @aerokite suggests: `myMount := mount.Mount{Type: volume.TypeVolume Source: myVolume.Name Target: "/var/lib/postgresql/data"}` – Tom Mertz May 30 '18 at 23:30
  • @TomMertz, saved my day. Note that it should be `Type: mount.TypeVolume` and not `Type: volume.TypeVolume`. – Eysi Oct 24 '18 at 09:39
3

The accepted answer worked great for directories, but it did not work for single files. It ends up getting mounting the file as a directory inside the container even if the file exists on the host. Inspecting how it works in the Docker CLI, it uses the Binds instead of Mounts and then the Mounts ends up getting automatically populated. This is how it looks in the Go code to mount a single file:

res, err := client.ContainerCreate(
    ctx,
    &container.Config{
        Image: "nginx",
        Cmd:   []string{"ls", "/"},
    },
    &container.HostConfig{
        Binds: []string{
            "/localPath:/pathInDocker",
        },
    },
    nil,
    "",
)
ryanbrainard
  • 5,918
  • 35
  • 41