Docker-compose, Windows 10/Linux/Bamboo and containers’ IP address

Last time I was playing a little bit with setting up a Docker-compose environment with couple of applications running in separate containers and communicating with them from the host machine. A program running on a host machine needed to know IP address and port number mapped to a given containerized application. The aim was to prepare an infrastructure in an OS-independent way. Unfortunately it looks that Docker-compose for Linux works a little bit different that Docker-compose for Windows (at least in Docker Toolbox variant).

Containers were configured to use network mode “bridge”, so containerized applications could communicate between each other. Each container exposed one port that should be mapped by Docker-compose to a dynamically allocated port accessible from the host machine. Those ports can be easily established based on the output of docker-compose ps command.

How to establish IP address?

Please note that we’re not interested in internal IP addresses of containers used in inter-container communication. We would like to know the IP address used from the host machine to communicate with containers.

Windows

It turned out that under Windows (Windows 10, Docker Toolbox for Windows) to establish IP address that is used on the host machine to communicate with containerized applications one needs to use the docker-machine command:

docker-machine ip

The IP address returned by this command is the one assigned to a virtual machine created internally by Docker-compose on Windows to implement containers. And this is a kind of a surprise for beginners.

Linux

On the other hand, under Linux, the IP address used on the host machine to communicate with containerized applications is just… a local host address 127.0.0.1 (or localhost).

But wait! This doesn’t work when Docker containers are started by a job on Atlassian Bamboo server which itself is running under Linux. I was facing “connection refused” error in this case. So according to point 2 of step 4 in “Get started with Docker Compose” document (official Docker documentation!) there is a second option: use IP address of 0.0.0.0

This worked on my computer with Linux but again it didn’t work in Atlassian Bamboo environment which seemed to be Linux environment! But it looks like Bamboo agents are running in Docker. Or at least they can run in Docker (Bamboo server was out of my control so I wasn’t sure). So it’s possible this was a case of running Docker containers inside a Docker container!

Solution for Linux and for Atlassian Bamboo

The universal solution for establishing correct IP that works under Linux and in Atlassian Bamboo (if it runs under Linux) is to determine the IP of a network interface created by Docker to provide its network mode “bridge”. There are couple of ways how to determine:

  1. Use command docker network inspect bridge and look for line with “Gateway” (in the example below the IP is 172.17.0.1):
    $ docker network inspect bridge
    [
        {
            "Name": "bridge",
            "Id": "7f08d9b766b7ac71c6a87f049f2e9908137d03fd4e5ea682f3d7b9009359f756",
            "Created": "2018-02-21T17:02:29.521034216+01:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": null,
                "Config": [
                    {
                        "Subnet": "172.17.0.0/16",
                        "Gateway": "172.17.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Containers": {},
            "Options": {
                "com.docker.network.bridge.default_bridge": "true",
                "com.docker.network.bridge.enable_icc": "true",
                "com.docker.network.bridge.enable_ip_masquerade": "true",
                "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
                "com.docker.network.bridge.name": "docker0",
                "com.docker.network.driver.mtu": "1500"
            },
            "Labels": {}
        }
    ]
    
  2. Use command ifconfig and look for something like docker0 interface:
    $ ifconfig
    docker0   Link encap:Ethernet  HWaddr 01:41:16:d1:e1:01  
              inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
    ...
    
  3. Use “docker inspect” command with ID of any of your running Docker containers and look for NetworkSettings.Gateway property. Sample output.
  4. If any of above methods is not available (still possible under Bamboo) then use Docker-client library made by Spotify. For me this Java code worked to get the IP:
    DockerClient dockerClient = DefaultDockerClient.fromEnv().build();
    ContainerInfo info = dockerClient.inspectContainer(dockerContainerId);
    String ipAddress = info.networkSettings().gateway();
    

This single approach of establishing IP to communicate with Docker containers worked for me if my environment setup script just detected Linux, no matter if it was running on my Linux box or under Bamboo (running under Linux as well).

Summary

Docker-compose is mostly great in unifying runtime environment however establishing IP address to communicate with containers from outside of Docker is still not unified. The problems are not only introduced by Windows OS. The case I’ve experienced with Atlassian Bamboo shows network related problem with Docker can appear in other circumstances as well. :-\

Advertisements

About krzysztoftomaszewski

I've got M.Sc. in software engineering. I graduated in 2005 at Institute of Computer Science, Warsaw University of Technology, Faculty of Electronics and Information Technology. I'm working on computer software design and engineering continuously since 2004.
This entry was posted in Docker, Linux and tagged , , , , . Bookmark the permalink.

One Response to Docker-compose, Windows 10/Linux/Bamboo and containers’ IP address

  1. Matt says:

    I had this issue before, where I needed to pass the IP address of the host to a container, and you can just use “host.docker.internal” in a environment variable in docker compose (at least that’s how I used it), and that worked.

    But that works for mac and windows, don’t know if this works for Linux, https://github.com/docker/for-linux/issues/264 seems to indicate they’re working on it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s