Localhost and docker-compose networking issue

Now that Docker for Mac uses localhost instead of an IP, should communication between docker containers and non-docker containers be possible using localhost for all? I have docker services and non-docker services running and I need them to read from a DB in docker, but I keep getting this when calling the container for dynamodb-local.

Failed to open TCP connection to localhost:8000 (Connection refused - connect(2) for “localhost” port 8000)

In my docker-compose.yml I define the dependency

patient-processor:
image: matchbox/nci-match-patient-processor:latest
entrypoint: /docker-compose-env.sh
depends_on:
- dynamodb
ports:
- “3010:3010”
environment:
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
- RAILS_ENV=development
dynamodb:
image: matchbox/dynamodb-local:latest
ports:
- “8000:8000”

From the docker-compose networking doc (https://docs.docker.com/compose/networking/) it looks like all of the containers should be set up on a shared network to talk to each other. I can reach the running services from a browser with http://localhost:port, but not the dynamo-local container. I’m trying to figure out if I have a dynamo issue, or a docker networking issue.
My questions are

  1. Cross-container networking: Can the containers call each other by localhost:port (localhost:8000 for example) or can they only use the compose name like dynamodb:8000?
  2. Cross-system networking: Can the non-docker services running locally use the db at localhost:8000?
2 Likes

localhost always (every platform, every Docker setup) refers to the container itself and never to anything running in any other container or the host system. (Unless you’re running a container with --net host, which is odd on Docker for Mac.)

On every platform with every Docker setup, if you can identify a “real” IP address for the host system, you can use it to connect to services that are running there, including other Docker containers that publish ports with docker run -p. Some platforms/setups provide a bridge address that you can use to access the host system (frequently 172.17.0.1/16 on native Linux and 192.168.99.100/24 on Docker Toolbox/Docker Machine) but Docker for Mac does not have this.

localhost always refers to the current container. You have to use the compose name.

Since you declare that as a published port with a Docker Compose ports section, yes.

1 Like

Thanks for the response @dmaze. The struggle I’m having is that when I bring up a docker application such as a web server, it registers port 80:80 with the host and I can reach it by calling localhost:80 on my Mac. Yes the service’s localhost is the docker container, but my host machine has 80 registered to it, left side right side of the 80:80 -p flag. This works for most of my docker containers, but when I start dynamodb-local and register 8000:8000 I don’t seem to be able to reach it as localhost:8000 as I do other containers with host mapped ports. Any idea why?

My objective is the easiest way to use dynamodb-local (running in a docker container) by both other dockers, and applications on my Mac. I’m open to suggestions.

Below you’ll find a subset of a docker-compose file I’m using. I’m able to access DDB shell at http://localhost:8000/shell/

dynamodb:
  container_name: dynamodb
  image: aleveille/dynamodb:latest
  volumes:
    - dynamodb-home:/var/lib/docker/dynamo/home
    - dynamodb-data:/var/lib/docker/dynamo/data
  ports:
   - "8000:8000"
  networks:
   - default
volumes:
  dynamodb-home:
  dynamodb-data:
  • Note: there are much better DynamoDB images out there. We just happen to use a custom one and I didn’t bother trying with another image.
1 Like

Using network_mode: host on the service patient-processor, your patient-processor container it’s in your host network and dynamodb export the port 8000 in you host network; in this way
you can call dynamodb using localhost:8000 inside you patient-processor container

patient-processor:
  image: matchbox/nci-match-patient-processor:latest
  entrypoint: /docker-compose-env.sh
  network_mode: host
  depends_on:
    - dynamodb
  ports:
    - "3010:3010"
  environment:
    - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
    - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
    - RAILS_ENV=development
dynamodb:
  image: matchbox/dynamodb-local:latest
  ports:
    - “8000:8000”
1 Like

Did a lot of digging around this issue and finally came across this in Docker’s own docs: Explore networking features on Docker Desktop | Docker Docs. This line in particular:

The host has a changing IP address (or none if you have no network access). From 18.03 onwards our recommendation is to connect to the special DNS name host.docker.internal , which resolves to the internal IP address used by the host. This is for development purpose and will not work in a production environment outside of Docker for Mac.

This worked like a charm for me!

2 Likes

you’re beautiful. Thanks