Adventures in HttpContext All the stuff after 'Hello, World'

Accessing the Docker Host Server Within a Container

Docker links are a great way to link two containers together but sometimes you want to know more about the host and network from within a container. You have a couple of options:

  • You can access the Docker host by the container’s gateway.
  • You can access the Docker host by its ip address from within a container.

The Gateway Approach

This GitHub Issue outlines the solution. Essentially you’re using netstat to parse the gateway the docker container uses to access the outside world. This is the docker0 bridge on the host.

As an example, we’ll run a simple docker container which returns the hostname of the container on port 8080:

docker run -d -p 8080:8080 mhamrah/mesos-sample

Next we’ll run /bin/bash in another container to do some discovery:

docker run -i -t ubuntu /bin/bash
#once in, install curl:
apt-get update
apt-get install -y curl

We can use the following command to pull out the gateway from netstat:

netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'
#returns 172.17.42.1 for me.

We can then curl our other docker container, and we should get that docker container’s hostname:

curl 172.17.42.1:8080
# returns 00b019ce188c

Nothing exciting, but you get the picture: it doesn’t matter that the service is inside another container, we’re accessing it via the host, and we didn’t need to use links. We just needed to know the port the other service was listening on. If you had a service running on some other port–say Postgres on 5432–not running in a Docker container–you can access it via 172.17.42.1:5432.

If you have docker installed in your container you can also query the docker host:

# In a container with docker installed list other containers running on the host for other containers:
docker -H tcp://172.17.42.1:2375 ps
CONTAINER ID        IMAGE                         COMMAND                CREATED              STATUS              PORTS                     NAMES
09d035054988        ubuntu:14.04                  /bin/bash              About a minute ago   Up About a minute   0.0.0.0:49153->8080/tcp   angry_bardeen
00b019ce188c        mhamrah/mesos-sample:latest   /opt/delivery/bin/de   8 minutes ago        Up 8 minutes        0.0.0.0:8080->8080/tcp    suspicious_colden

You can use this for some hakky service-discovery.

The IP Approach

The gateway approach is great because you can figure out a way to access a host from entirely within a container. You also have the same access via the host’s ip address. I’m using boot2docker, and the boot2docker ip address is 192.168.59.103 and I can accomplish the same tasks as the gateway approach:

# Docker processes, via ip:
docker -H tcp://192.168.59.103:2375 ps
# Other docker containers, via ip:
curl 192.168.59.103:8080

Although there’s no way to introspect the host’s ip address (AFAIK) you can pass this in via an environment variable:

docker@boot2docker:~$  docker run -i -t -e DOCKER_HOST=192.168.59.103 ubuntu /bin/bash
root@07561b0607f4:/# env
HOSTNAME=07561b0607f4
DOCKER_HOST=192.168.59.103
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/

If the container knows the ip address of its host, you can broadcast this out to other services via the container’s application. Useful for service discovery tools run from within a container where you want to tell others the host IP so others can find you.