Srinath Ganesh
Srinath Ganesh

Reputation: 2558

Docker Compose: Expose not working

docker-ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                NAMES
83b1503d2e7c        app_nginx      "nginx -g 'daemon ..."   2 hours ago         Up 2 hours                  0.0.0.0:80->80/tcp   app_nginx_1
c9dd2231e554        app_web        "/home/start.sh"         2 hours ago         Up 2 hours                  8000/tcp             app_web_1
baad0fb1fabf        app_gremlin    "/start.sh"              2 hours ago         Up 2 hours                  8182/tcp             app_gremlin_1
b663a5f026bc        postgres:9.5.1 "docker-entrypoint..."   25 hours ago        Up 2 hours                  5432/tcp             app_db_1

They all work fine:

No working file:

docker-compose.yaml

version: '3'
services:
  db:
    image: postgres:9.5.12
  web:
    build: .
    expose:
      - "8000"
    depends_on:
      - gremlin
    command: /home/start.sh
  nginx:
    build: ./nginx
    links:
        - web
    ports:
        - "80:80"
    command: nginx -g 'daemon off;'
  gremlin:
    build: ./gremlin
    expose:
      - "8182"
    command: /start.sh

Errors:

Basically I am not able to connect to gremlin container from my app_web container.

All below have been executed inside web_app container

curl:

root@49a8f08a7b82:/# curl 0.0.0.0:8182
curl: (7) Failed to connect to 0.0.0.0 port 8182: Connection refused

netstat

root@49a8f08a7b82:/# netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.11:42681        0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN     
udp        0      0 127.0.0.11:54232        0.0.0.0:*                          
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node   Path

nmap

root@49a8f08a7b82:/# nmap -p 8182 0.0.0.0

Starting Nmap 7.60 ( https://nmap.org ) at 2018-06-22 09:28 UTC
Nmap scan report for 0.0.0.0
Host is up.

PORT     STATE    SERVICE
8182/tcp filtered vmware-fdm

Nmap done: 1 IP address (1 host up) scanned in 2.19 seconds

nslookup

root@88626de0c056:/# nslookup app_gremlin_1 Server: 127.0.0.11 Address: 127.0.0.11#53

Non-authoritative answer: Name: app_gremlin_1 Address: 172.19.0.3


Experimenting:

For Gremlin container I did,

ports:
      - "8182:8182"

Then from Host I can connect to gremlin container BUT still no connection between web and gremlin container


I am working on creating a re-creating sample Docker file (minimal stuff to recreate the issue) meanwhile anyone has any idea what the issue might be?

Upvotes: 3

Views: 8324

Answers (2)

BMitch
BMitch

Reputation: 263597

curl 0.0.0.0:8182

The 0.0.0.0 address is a wild card that tells an app to listen on all network interfaces, you do not connect to this interface as a client. For container to container communication, you need:

  • containers on the same user generated network (compose does this for you by default)
  • connect to the name of the service (or container name)
  • connect to the port inside the other container, not the published port.

In your case, the command should be:

curl http://gremlin:8182

Networking is namespaced in apps running inside containers, so each container gets it's open loopback interface and ip address on a bridge network. So moving an app into containers means you need to listen on 0.0.0.0 and connect to the bridge ip using DNS.

You should also remove links and depends_on from your Dockerfile, they don't apply in version 3. Links have long since been deprecated in favor of shared networks. And depends_on doesn't work in swarm mode along with probably not doing what you wanted since it never checked for the target app to be running, only the start of that container to have been kicked off.

One last note, expose doesn't affect the ability to communicate between containers on common networks or publish ports on the host. Expose simply sets meta data on the image that is documentation between the person creating the image and the person running the image. Applications are not required to use that value, but it's a good habit to make your app default to that value for the benefit of downstream users. Because of its role, unless you have another app checking for the exposed port list, like a self updating reverse proxy, there's no need to expose the port in the compose file unless you're giving the compose file to another person and they need the documentation.

Upvotes: 8

Ignacio Millán
Ignacio Millán

Reputation: 8026

There is no link configured in the docker-compose.yaml between web and gremlin. Try to use the following:

version: '3'
services:
  db:
    image: postgres:9.5.12
  web:
    links:
      - gremlin
    build: .
    expose:
      - "8000"
    depends_on:
      - gremlin
    command: /home/start.sh
  nginx:
    build: ./nginx
    links:
        - web
    ports:
        - "80:80"
    command: nginx -g 'daemon off;'
  gremlin:
    build: ./gremlin
    expose:
      - "8182"
    command: /start.sh

Upvotes: 5

Related Questions