user2609980
user2609980

Reputation: 10484

Reach host with Docker Compose

I have a Docker Compose v2 file which starts a container. I locally run a service on port 3001. I want to reach this service from the Docker container.

The Docker Compose file looks like this:

version: '2'
services:
  my-thingy:
    image: my-image:latest
    #network_mode: host #DOES not help
    environment:
      - THE_HOST_I_WANT_TO_CONNECT_TO=http://127.0.0.1:3001
    ports:
  - "3010:3010"

Now, how can I reach THE_HOST_I_WANT_TO_CONNECT_TO?

What I tried is:

Upvotes: 1

Views: 1270

Answers (2)

akavel
akavel

Reputation: 4875

I've used another hack/workarkound from comments in the docker issue #1143. Seems to Work For Me™ for the time being... Specifically, I've added the following lines in my Dockerfile:

# - net-tools contains netstat, used to discover IP of Docker host server.
#   NOTE: the netstat trick is to make Docker host server accessible
#   from inside Docker container under name 'dockerhost'. Unfortunately,
#   as of 2016.10, there's no official/robust way to do this when Docker host
#   has no public IP/DNS entry. What is used here is built based on:
#   - https://github.com/docker/docker/issues/1143#issuecomment-39364200
#   - https://github.com/docker/docker/issues/1143#issuecomment-46105218
#   See also:
#   - http://stackoverflow.com/q/38936738/98528
#   - https://github.com/docker/docker/issues/8395#issuecomment-200808798
#   - https://github.com/docker/docker/issues/23177
RUN apt-get update && apt-get install -y net-tools
CMD (netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2" dockerhost"}' >> /etc/hosts) && \
        ...old CMD...

With this, I can use dockerhost as the name of the host where Docker is installed. As mentioned above, this is based on:

  • https://github.com/docker/docker/issues/1143#issuecomment-39364200

    (...) One way is to rely on the fact that the Docker host is reachable through the address of the Docker bridge, which happens to be the default gateway for the container. In other words, a clever parsing of ip route ls | grep ^default might be all you need in that case. Of course, it relies on an implementation detail (the default gateway happens to be an IP address of the Docker host) which might change in the future. (...)

  • https://github.com/docker/docker/issues/1143#issuecomment-46105218

    (...) A lot of people like us are looking for a little tidbit like this

    netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'
    

where netstat -nr means:

Netstat prints information about the Linux networking subsystem.
(...)
--route , -r
Display the kernel routing tables.
(...)
--numeric , -n
Show numerical addresses instead of trying to determine symbolic host, port or user names.

Upvotes: 2

user2609980
user2609980

Reputation: 10484

This is a known issue with Docker Compose: see Document how to connect to Docker host from container #1143. The suggested solution of a dockerhost entry in /etc/hosts is not implemented.

I went for the solution with a shell variable as also suggested in a comment by amcdl on the issue:

Create a LOCAL_XX_HOST variable: export LOCAL_XX_HOST="http://$(ifconfig en0 inet | grep "inet " | awk -F'[: ]+' '{ print $2 }'):3001".

Then, for example, refer to this variable in docker-compose like this:

my-thingy:
    image: my-image:latest
    environment:
      - THE_HOST_I_WANT_TO_CONNECT_TO=${LOCAL_XX_HOST}

Upvotes: 2

Related Questions