8

I have a setup with docker in docker and try to mount folders.

Let's say I have those folders that I wish to share with his parent. On the host, I created a file in /tmp/dind called foo. Host starts container 1, which starts container 2. This is the result I want to have.

Host      | Container 1 | Container 2

/tmp/dind |  /tmp/dind2 | /tmp/dind3
      <------->     <------->

Instead, I get

Host      | Container 1 | Container 2

/tmp/dind |  /tmp/dind2 | /tmp/dind3
      <------->
      <----------------------->

Code here:

docker run --rm -it \
  -v /tmp/dind:/tmp/dind2 \
  -v /var/run/docker.sock:/var/run/docker.sock docker sh -c \
    "docker run --rm -it \
      -v /tmp/dind2:/tmp/dind3 \
      -v /var/run/docker.sock:/var/run/docker.sock \
      docker ls /tmp/dind3"

This outputs nothing, while the next command gives foo as result. I changed the mounted volume:

docker run --rm -it \
  -v /tmp/dind:/tmp/dind2 \
  -v /var/run/docker.sock:/var/run/docker.sock docker sh -c \
    "docker run --rm -it \
      -v /tmp/dind:/tmp/dind3 \
      -v /var/run/docker.sock:/var/run/docker.sock \
      docker ls /tmp/dind3"

The question is, what do I need to do in order to use Container 1 path and not host? Or do I misunderstand something about docker here?

David Maze
  • 130,717
  • 29
  • 175
  • 215
David Bensoussan
  • 2,887
  • 2
  • 38
  • 55

2 Answers2

8

For all that you say “Docker-in-Docker” and “dind”, this setup isn’t actually Docker-in-Docker: your container1 is giving instructions to the host’s Docker daemon that affect container2.

Host      Container1
    /-----
 (Docker)
    |     Container2
    \---->

(NB: this is generally the recommended path for CI-type setups. “Docker-in-Docker” generally means container1 is running its own, separate, Docker daemon, which tends to not be recommended.)

Since container1 is giving instructions to the host’s Docker, and the host’s Docker is launching container2, any docker run -v paths are always the host’s paths. Unless you know that some specific directory has already been mounted into your container, it’s hard to share files with “sub-containers”.

One way to get around this is to assert that there is a shared path of some sort:

docker run \
  -v $PWD/exchange:/exchange \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e EXCHANGE_PATH=$PWD/exchange \
  --name container1
  ...

# from within container1
mkdir $EXCHANGE_PATH/container2
echo hello world > $EXCHANGE_PATH/container2/file.txt
docker run \
  -v $EXCHANGE_PATH/container2:/data
  --name container2
  ...

When I’ve done this in the past (for a test setup that wanted to launch helper containers) I’ve used a painstaking docker create, docker cp, docker start, docker cp, Docker rm sequence. That’s extremely manual, but it has the advantage that the “local” side of a docker cp is always the current filesystem context even if you’re talking to the host’s Docker daemon from within a container.

David Maze
  • 130,717
  • 29
  • 175
  • 215
0

It does not matter if container 2 binds the host path, because the changes to files in container 1 directly affect everything on the host path. So they all work on the same files.

So your setup is correct and will function the same as if they referenced in the way you described.

Update
If you want to make sure that the process do not modify the host files you could do the following:

Build a custom docker images which copies all data from folder a to folder b, where you execute the script on folder b. And then mount the files with ./:/a. This way you maintain flexibility on which files you bind to the container without letting the container modify the host files.

I hope this answers your question :)

Sven Hakvoort
  • 3,543
  • 2
  • 17
  • 34
  • The thing is I don't want any modification in the host – David Bensoussan Nov 29 '18 at 13:17
  • 1
    @DavidBensoussan, what is the use case for which you want to do this? Because normally you would use volumes for data persistence which would mean that you do want modification on the host because otherwise it would be impossible to persist the data. So with that in mind I am curious as to what exactly you want to do/achieve with this – Sven Hakvoort Nov 29 '18 at 13:18
  • I have on my host a jenkins container running. one of the jobs starts a container to which I pass a folder. It's a script that will run against this folder. The other way would be to docker create, start and copy the folder. It would be more verbose than a simple docker run – David Bensoussan Nov 29 '18 at 13:22
  • @DavidBensoussan, I added a suggestion to my answer how you could achieve this. – Sven Hakvoort Nov 29 '18 at 13:26