Docker Container Networking with Docker-in-Docker

Viewed 8884

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!

3 Answers

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

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>
Related