Search code examples
dockerdocker-composeportdocker-network

Docker-compose dial tcp error with dynamic ip : port


I am trying to re-route request from gateway to a target service , and in case I am using static port binding everything works fine. But it is not flexible , so I want to run containers with dynamic ip and port in the network , to be able to run multiple instances.

I changed docker-compose.yml from

-ports: 
  "8082:8082"

to

-ports: 
  "8082"

And got an error

Get "http://c0000203.addr.dc1.consul.:60949/api/v1/users": dial tcp 192.0.2.3:60949: connect: connection refused

I am using consul as a service discovery , and registartor for registering containers

Base docker-compose file:

version: '3.7'
services:
  postgres:
    image: postgres:13
    restart: 'always'
    environment:
      - POSTGRES_DB=user-db
      - POSTGRES_PASSWORD=password
      - POSTGRES_USER=user
    ports:
      - "5432"
    networks:
      - vpcbr

  consul:
    image: consul:latest
    restart: 'always'
    environment:
      CONSUL_LOCAL_CONFIG: |
        {
          "recursors": [
            "8.8.8.8",
            "8.8.4.4"
          ],
          "dns_config": {
            "recursor_strategy": "random"
          },
          "ports": {
            "dns": 53
          }
        }
    networks:
      vpcbr:
        ipv4_address: 192.0.2.10
    ports:
      - '8500:8500'
      - '53/tcp'
      - '53/udp'

  registrator:
    image: gliderlabs/registrator:latest
    command: "consul://consul:8500"
    container_name: registrator
    depends_on:
      - consul
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    networks:
      vpcbr:
        ipv4_address: 192.0.2.20

  krakend_gateway:
    image: devopsfaith/krakend:2
    command: [ "run", "-d", "-c", "/krakend.json" ]
    dns: 192.0.2.10
    volumes:
      - ./krakend-gateway/krakend.json:/krakend.json
    ports:
      - "1234:1234"
      - "8080:8080"
      - "8090:8090"
    networks:
      vpcbr:
        ipv4_address: 192.0.2.23

  user-ms:
    build: user-ms/
    platform: linux/arm64
    restart: 'always'
    depends_on: [consul, krakend_gateway]
    networks:
      - vpcbr
    ports:
      - "8082"

networks:
  vpcbr:
    driver: bridge
    ipam:
      config:
        - subnet: 192.0.2.0/24

Service which is sending request is Krakend , target service is user-ms , which should accept this request , everything is work when I am changing user-ms port binding to "8082:8082"

Will be glad if someone could help me , thanks


Solution

  • Use Registrator's -internal CLI flag to configure to register services with the internal IP addresses of the Docker container, not the external host IP.

    Per https://gliderlabs.github.io/registrator/latest/user/run/#registrator-options

    • -internal Use exposed ports instead of published ports.

    If the -internal option is used, Registrator will register the docker0 internal IP and port instead of the host mapped ones.

    The modified container definition will then be as follows.

    # docker-compose.yaml
    ...
      registrator:
        image: gliderlabs/registrator:latest
        command: "consul://consul:8500 -internal"
        container_name: registrator
        depends_on:
          - consul
        volumes:
          - /var/run/docker.sock:/tmp/docker.sock
        networks:
          vpcbr:
            ipv4_address: 192.0.2.20
    ...