-1

I would like to run my docker containers in a sandbox docker environment. So, I use Docker-in-Docker DinD.

I use docker-compose.yaml to define the sandbox:

version: '3.8'
services:
  docker:
    hostname: docker
    container_name: dind
    image: docker:latest
    privileged: yes

  myapp:
    hostname: myapp
    container_name: myapp
    image: foox/myapp:1.1.0
    ports: 
     - 8080:8080

But I get confused now, if I run the docker-compose up with this, how does Docker running on my host know whether myapp service should be launched by host docker or the DinD?

What are the key statements I should include in my above docker-compose.yaml in order to explicitly tell that run myapp inside the DinD instead of the host docker?

user842225
  • 5,445
  • 15
  • 69
  • 119
  • You'll need a second Compose file for your application; Compose assumes all of the containers it starts go with the same Docker. Do you actually need DinD here, or can you just run `myapp`? – David Maze Mar 18 '23 at 10:39
  • Thanks @DavidMaze , would be nice if you could show an example in an answer. Yes, I have a special need to use DinD, I just simplified my environment in the question. – user842225 Mar 18 '23 at 11:12
  • I'd probably create a normal Compose setup that didn't use DinD at all, then if I really actually needed the DinD container (IME this is quite unusual) start it up separately, set `$DOCKER_HOST` to point at it, and run `docker-compose up` normally but pointing at the other Docker instance. You can't put both the application and the DinD instance you want to run it in both in the same Compose file. – David Maze Mar 18 '23 at 11:30
  • Thanks again. That will work for sure. But my question is mainly based on my curiosity on how DinD works when using docker-compose (having services there running in the DinD) since I see people do that but I don't understand how it works. So, whether using DinD or using it another way is actually outside my question context, though I understand your point. Thank you anyway. – user842225 Mar 18 '23 at 12:20

1 Answers1

0

You're trying to tell Compose to create containers in two different Docker instances. One container should go in the normal host Docker environment, but you're asking for the other to be run in the Docker-in-Docker environment. Compose doesn't have any way to do this; it expects everything it creates (containers, networks, volumes) to belong to "the same" Docker.

To make this work, you should make a normal Compose setup that will run your application. Of particular note, since you're planning to run this in an environment that's not your local system, make sure you don't have any volumes: that reference local files. This is the same Compose setup that could run the application locally, or in principle against a remote Docker.

version: '3.8'
services:
  myapp:
    image: foox/myapp:1.1.0
    ports: 
     - 8080:8080

You can run docker-compose up -d on your host system normally, and this should be enough for most normal uses -- you almost never need Docker-in-Docker and in my experience it is very unusual to see it at all.

If you do need DinD, you need to start the Docker daemon container, and then you need to tell the various Docker tools how to reach it. If you wanted to launch it via Compose, you'd need a separate Compose file that only included the DinD container

version: '3.8'
services:
  docker:
    image: docker:dind
    privileged: true
    ports: ['127.0.0.1:12375:2375']

Then you need to start this nested Docker daemon and point Compose at it.

docker-compose -f docker-compose.dind.yaml up -d
DOCKER_HOST=tcp://localhost:12375 docker-compose up -d

Note that this setup allows unencrypted and unauthenticated access to the nested Docker daemon; while it's running in a container, it is a privileged container and there is still some damage that can be done by any local process. The Docker Hub docker image page describes a more robust setup with TLS certificates, and an even better approach of not publishing ports: out of the DinD container at all.

If all of this makes the Docker-in-Docker setup sound hard to use, it is, and conventional advice is to avoid it, even in CI systems where it might seem useful to give each build its own fully-isolated Docker setup.

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Thanks for the detailed answer. Please let me give an example of what I see people is doing it in one compose file, it is this Udemy course repo, where, the compose file has both DinD container & other containers running inside the DinD in one docker-compose file, but I don't understand why & how it can work & it indeed works. https://github.com/spurin/diveintoansible-lab/blob/master/docker-compose.yaml , if you see line 127 DinD container is there. I need an answer that could explain what are the key things that make it work in that way (in one compose file) – user842225 Mar 18 '23 at 21:32
  • It looks like that file tries to launch a half-dozen Linux VMs of various distributions, each with their own interactive login system, plus an auxiliary Docker daemon for good measure. That doesn't seem like a typical or best-practice Docker setup to me at all, and I wouldn't expect any of the various sshd containers to be running inside the nested DinD container. – David Maze Mar 18 '23 at 21:48
  • Are you sure? I found another example, on youtube (the 1st 3 seconds shows the compose yaml) https://www.youtube.com/watch?v=qDrbtOv20xc, it also use the same approach to launch Jenkins container inside DinD container & both are defined in one compose file. I am now guessing the key thing to make it work is actually they use the same `network`, what do you think? So, the previous example of various Linux distros also works inside DinD for the same reason & they both defined in one compose file. – user842225 Mar 18 '23 at 21:52
  • I tried both examples myself, it looks like those are fake examples that the containers are not running inside the DinD container. I don't know why some people spread the false information to mislead, but your answer is probably correct. – user842225 Mar 19 '23 at 10:06