1

I am trying to run docker inside container using Go Docker Engine API. I am able to mount a folder from host system to the container but only empty dir is being copied into the docker inside the container. Please help me out if there is any alternative for the same. I am starting my container using following command.

docker run --rm -v C:\Users\user\source\repos\game:/app/myrepo -v /var/run/docker.sock:/var/run/docker.sock testimage

Attached is the piece of code. Go Docker SDK code to start container

resp, err := cli.ContainerCreate(ctx, &container.Config{
    Image: "hello-image",
    Cmd:   []string{"ls"}, #the actual cmd would look different
    Tty:   true,
}, &container.HostConfig{
    Binds: []string{
        "/app/myrepo:/myrepo",
    },
}, nil, nil, containername)
if err != nil {
    panic(err)
}

updated Code for binds with absolute path

resp, err := cli.ContainerCreate(ctx, &container.Config{
    Image: "hello-image",
    Cmd:   []string{"ls"}, #the actual cmd would look different
    Tty:   true,
}, &container.HostConfig{
    Mounts: []mount.Mount{
        {
            Type:   mount.TypeBind,
            Source: "/app/myrepo",
            Target: "/myrepo",
        },
    },
}, nil, nil, containername)
if err != nil {
    panic(err)
}
  • 1
    It looks like you are accessing the docker API from within a container and attempting to mount a folder using a path that is valid inside the container (not on the host). The [path passed to bind](https://docs.docker.com/storage/bind-mounts/) needs to be an "absolute path on the host machine" (i.e. whatever `%cd%` is returning on the host). – Brits Aug 21 '22 at 20:31
  • Thanks for your response @Brits . No luck, changed the code to **&container.HostConfig{ Mounts: []mount.Mount{ { Type: mount.TypeBind, Source: "/app/myrepo", Target: "/myrepo", }, }, // Binds: []string{ // "/app/myrepo:/myrepo", // },** But it still copies an empty myrepo folder into docker inside the container. – Syed Adil Shariq Aug 22 '22 at 03:19
  • Please edit your question with updates rather than posting code in a comment. It's difficult to comment because I don't know the value of `%cd%`; perhaps change that to a full path (that's the same path that you will need to use in your code). You are sending a command to the docker daemon; it will treat any paths as local to the machine its running on (it makes no difference if the request is local, from a container or over a network). – Brits Aug 22 '22 at 03:35
  • @Brits, updated my question, %cd% means current dir(windows). – Syed Adil Shariq Aug 22 '22 at 07:40
  • "%cd% means current dir" I'd guessed that but did not know what directory that was. Pass that path into the docker API - i.e. `Source: "c:/Users/user/source/repos/game",...` (using forward slashes to avoid the need to escape them). – Brits Aug 22 '22 at 09:09
  • It works like a charm. Thank you :) I was looking for a path relative to container where the docker is running instead of Host. – Syed Adil Shariq Aug 22 '22 at 13:26

1 Answers1

0

As discussed in the comments the OP is running an app in a container. The app is connecting to the docker daemon on the host (via shared /var/run/docker.sock) and attempting to create a container. The issue was that the request includes a mount point, the source being /app/myrepo, which a source path that is valid within the container but not on the host.

To aid in understanding why this is an issue you need to consider how the API request is made. Your code will generate a JSON formatted request; this will include something like this:

...
"HostConfig": {
   ...
   "Mounts": [
       {
           "Source": "/app/myrepo",
           "Destination": "/myrepo",        
       }
   ]
}

It's important to note that the Source path is passed as a string and the Docker Daemon will interpret this in the hosts (e.g. the windows box) context. When it attempts to locate the requested path (/app/myrepo) it will not find it because that path does not exist on the host. To correct this you need to send a valid path e.g.

Mounts: []mount.Mount{
   {
      Type:   mount.TypeBind,
      Source: "c:/Users/user/source/repos/game",
      Target: "/myrepo",
    },
}

One note of caution; accessing the Docker API in this way (bind mount /var/run/docker.sock:) is convenient but if someone gains access to the container then they also gain full control of all containers (because they can access the Docker API). You may want to consider using a proxy (for example).

Brits
  • 14,829
  • 2
  • 18
  • 31