31

I would like to network with a child docker container from a parent docker container, with a docker-in-docker setup.

Let's say I'm trying to connect to a simple Apache httpd server. When I run the httpd container on my host machine, everything works fine:

asnyder:~$ docker run -d -p 8080:80 httpd:alpine
asnyder:~$ curl localhost:8080
<html><body><h1>It works!</h1></body></html>

But when I do the same from a docker-in-docker setup, I get a Connection refused error:

asnyder:~$ docker run -d --name mydind --privileged docker:dind
asnyder:~$ docker run -it --link mydind:docker docker:latest sh
/ # docker run -d -p 8080:80 httpd:alpine
/ # curl localhost:8080
curl: (7) Failed to connect to localhost port 8080: Connection refused

I have tried a couple alterations without luck. Specifying the 0.0.0.0 interface:

asnyder:~$ docker run -d --name mydind --privileged docker:dind
asnyder:~$ docker run -it --link mydind:docker docker:latest sh
/ # docker run -d -p 0.0.0.0:8080:80 httpd:alpine
/ # curl 0.0.0.0:8080
curl: (7) Failed to connect to 0.0.0.0 port 8080: Connection refused

Using the host network:

asnyder:~$ docker run -d --name mydind --privileged docker:dind
asnyder:~$ docker run -it --link mydind:docker docker:latest sh
/ # docker run -d --network host httpd:alpine
/ # curl localhost:80
curl: (7) Failed to connect to localhost port 80: Connection refused

Surprisingly, I was unable to find any existing articles on this. Does anyone here have some insight?

Thanks!

Adam Snyder
  • 405
  • 1
  • 5
  • 7
  • Let me first ask you if you are sure you want a docker-in-docker setup? Read [this](http://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/) blog post first. – JonasVautherin Jul 05 '17 at 15:02
  • 8
    @JonesV I avoided getting into the specific scenario in the question to keep it general, but since you asked... I'm writing a [GitLab CI Pipeline Job](https://docs.gitlab.com/ee/ci/yaml/). Jobs in GitLab CI run inside a docker container that you can specify. I'm writing a Job that produces a PDF report based on some HTML, and I want to take advantage of an existing Docker image to do this. So, I have a docker-in-docker situation. I hope this helps clarify :) – Adam Snyder Aug 06 '17 at 03:00
  • I'm afraid I cannot help with the docker-in-docker setup. I just wanted to make sure your were aware of the points mentioned in the blog post =). – JonasVautherin Aug 06 '17 at 21:34
  • 8
    I had this exact same issue myself – GitLab CI using a `docker` image with a `docker:dind` service, and I also could connect from my own host, but not within the `docker` container. Very clear and well-posed question! – akivajgordon Mar 14 '18 at 04:16

3 Answers3

16

There are pros and cons for both DinD and bind mounting the Docker socket and there are certainly use cases for both. As an example, check out this set of blog posts, which does a good job of explaining one of the use cases.

Given your example docker-in-docker setup above, you can access Apache httpd server in one of two ways:

1) From inside the docker:dind container, it will be available on localhost:8080.

2) From inside the docker:latest container, where you were trying to access it originally, it will be available on whatever hostname is set for the docker:dind container. In this case, you used --name mydind, therefore curl mydind:8080 would give you the standard Apache <html><body><h1>It works!</h1></body></html>.

Hope it makes sense!

Yuriy Znatokov
  • 176
  • 1
  • 2
  • Both you guys are awesome! Thx! – dtk Jan 18 '19 at 10:24
  • What would cause the child container to not be accessible from the host container, e.g. localhost:8080 Failed to connect, connection refused (`curl`)? – Elijah Lynn Mar 02 '19 at 03:14
  • This is a good description of the issue I see when trying to access the child container on an exposed port from the host container: https://www.edureka.co/community/12457/docker-container-networking-with-docker-in-docker – Elijah Lynn Mar 02 '19 at 03:23
  • I am still struggling with this. is the link or a network needed between the parent and the dind contaner? – Travis Tubbs Mar 12 '19 at 16:00
12

Building upon Yuriy's answer:

2) From inside the docker:latest container, [...] it will be available on whatever hostname is set for the docker:dind container. In this case, you used --name mydind, therefore curl mydind:8080 [...]

In the Gitlab CI config, you can address the DinD container by the name of its image (in addition to the name of its container, which is auto-generated):

Accessing the services


Let’s say that you need a Wordpress instance to test some API integration with your application.

You can then use for example the tutum/wordpress image in your .gitlab-ci.yml:

services:
- tutum/wordpress:latest

If you don’t specify a service alias, when the job is run, tutum/wordpress will be started and you will have access to it from your build container under two hostnames to choose from:

  • tutum-wordpress
  • tutum__wordpress

Using

service:
- docker:dind

will allow you to access that container as docker:8080:

  script:
  - docker run -d -p 8080:80 httpd:alpine
  - curl docker:8080

Edit: If you'd prefer a more explicit host name, you can, as the documentation states, use an alias:

services:
- name: docker:dind
  alias: dind-service

and then

  script:
  - docker run -d -p 8080:80 httpd:alpine
  - curl dind-service:8080

Hth, dtk

dtk
  • 2,197
  • 2
  • 26
  • 19
  • 2
    What happens if in GitlabCI I use this script: `docker-compose -f docker-compose.yml up` and if I have a service called `mongodb` ? I seems that I can't use `mongodb` as a hostname. – Hugo Oct 01 '19 at 14:43
  • @Hugo were you able to figure your query out? – Shan-Desai Jun 14 '22 at 14:25
  • @Shan-Desai hey - sorry it was a while ago - I really can't recall :/ – Hugo Jun 15 '22 at 16:22
1

I am very convinced that @Yuriy Znatokov's answer is what I want, but I have understood it for a long time. In order to make it easier for later people to understand, I have exported the complete steps.

1) From inside the docker:dind container

docker run -d --name mydind --privileged docker:dind
/ # docker run -d -p 8080:80 httpd:alpine
/ # curl localhost:8080
<html><body><h1>It works!</h1></body></html>

2) From inside the docker:latest container

docker run -d --name mydind --privileged docker:dind
docker run -it --link mydind:docker docker:latest sh
/ # docker run -d -p 8080:80 httpd:alpine
/ # curl mydind:8080
<html><body><h1>It works!</h1></body></html>
xiaoxinmiao
  • 317
  • 1
  • 3
  • 10