7

I am trying to connect two locally developed projects running on docker-compose by using external networking.

From one side I have an 1st application intended to be exposed. Compose contains hosts: app and rabbit:

version: '3.4'

services:
  app:
    # ...
  rabbit:
    # ...

networks:
  default:
    driver: bridge

From other side I have second application expected to see 1st application:

version: '3.4'

services:
  app:
    # ...
    networks:
      - paymentservice_default
      - default

networks:
  paymentservice_default:
    external: true

Reaching host rabbit.paymentservice_default is possible.

However service app (1st) conflicts with app (2nd):

root@6db86687229c:/app# ping app.paymentservice_default
PING app.paymentservice_default (192.168.80.6) 56(84) bytes of data.

root@6db86687229c:/app# ping app
PING app (192.168.80.6) 56(84) bytes of data.

In general from 2nd compose perspective hosts app and app.paymentservice_default shares same IP making app.paymentservice_default undiscoverable.

The question here is, do I have proper configuration and conflict can be avoided without changing service names app? Why this constraint? Taking consideration that every docker-compose configuration is shared across projects and can be developed in micro-services world.

$ docker-compose --version
docker-compose version 1.17.1, build unknown
$ docker --version
Docker version 19.03.4, build 9013bf583a

Thank you.

Athlan
  • 6,389
  • 4
  • 38
  • 56
  • If you specify any `networks:`, the `app` container won't be attached to its own Compose file's `default` network; you need to explicitly list it. I can't tell if that will help your issue though. – David Maze Oct 20 '19 at 17:02
  • Yes you're right. I'll update question. However, this network is not a problem. – Athlan Oct 20 '19 at 17:20
  • 1
    try to add `-p project_name` when you run `docker-compose up` – rok Oct 20 '19 at 17:51
  • Better to go for swarm services ( if not K8s ) – Soumen Mukherjee Oct 20 '19 at 17:54
  • 2
    Have you tried [alias](https://docs.docker.com/compose/compose-file/compose-file-v2/#aliases) yet? – Toan Quoc Ho Oct 20 '19 at 18:01
  • @rok I'm using `COMPOSE_PROJECT_NAME`, same purpose, works as cited (see network name). @Soumen - that's another topic, question is compose-related. – Athlan Oct 20 '19 at 18:01
  • Does this answer your question? [Docker DNS with Multiple Projects Using the Same Network](https://stackoverflow.com/questions/54506950/docker-dns-with-multiple-projects-using-the-same-network) – maiermic Jul 24 '21 at 16:40

1 Answers1

2

I use the following configuration on Docker Playground

paymentservice.docker-compose.yml

version: '3.4'

services:
  app:
    image: busybox
    # keep container running
    command: tail -f /dev/null
  rabbit:
    image: rabbitmq

networks:
  default:
    driver: bridge

other.docker-compose.yml

version: '3.4'

services:
  app:
    image: busybox
    # keep container running
    command: tail -f /dev/null
    networks:
      - paymentservice_default
      - default

networks:
  paymentservice_default:
    external: true

Run both projects

$ COMPOSE_PROJECT_NAME=paymentservice docker-compose -f paymentservice.docker-compose.yml up -d
$ COMPOSE_PROJECT_NAME=other docker-compose -f other.docker-compose.yml up -d

Show Docker IPs

$ docker ps -q | xargs -n 1 docker inspect --format '{{ .Name }} {{range .NetworkSettings.Networks}} {{.IPAddress}}{{end}}' | sed 's#^/##';

I got

other_app_1  172.20.0.2 172.19.0.4
paymentservice_app_1  172.19.0.3
paymentservice_rabbit_1  172.19.0.2

and I pinged paymentservice_app_1 (172.19.0.3) from other_app_1 using app.paymentservice_default

$ docker exec -it other_app_1 ping -c 1 app.paymentservice_default
PING app.paymentservice_default (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.258 ms

--- app.paymentservice_default ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.258/0.258/0.258 ms

and I pinged other_app_1 (172.20.0.2) from other_app_1 using app

$ docker exec -it other_app_1 ping -c 1 app
PING app (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.054 ms

--- app ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.054/0.054/0.054 ms

As you can see, I can access the 1st app (of paymentservice.docker-compose.yml) from the 2nd app (of other.docker-compose.yml).

The same works in the other direction. I pinged other_app_1 (172.19.0.4) from paymentservice_app_1 using app.paymentservice_default

$ docker exec -it paymentservice_app_1 ping -c 1 app.paymentservice_default
PING app.paymentservice_default (172.19.0.4): 56 data bytes
64 bytes from 172.19.0.4: seq=0 ttl=64 time=0.198 ms

--- app.paymentservice_default ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.198/0.198/0.198 ms

I pinged paymentservice_app_1 (172.19.0.3) from paymentservice_app_1 using app

$ docker exec -it paymentservice_app_1 ping -c 1 app
PING app (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.057 ms

--- app ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.057/0.057/0.057 ms

As you can see, I can access app service of both projects. If I like to access the service of the same project, I use the default network of the project. If I'd like to access the service of another project, I use the external network shared between both projects.

Note: I would recommend to make this more explicit by creating the shared network outside of the projects using the command line

docker network create shared-between-paymentservice-and-other

and declaring it as external in both projects.

Note: There is still the limitation that service discovery may not work if you have 3 projects with the same service name (e.g. app) in the same (external) network (sort of a namespace). In that case, it might be a better idea to rename your services, use multiple external networks, define aliases or use a totally different approach to discover/identify the Docker containers.


Afterword

Has that been the requirement? I tried to reproduce your issue, but I'm not sure if I did the same as you. For example, I'm not sure, where you are running ping. Is root@6db86687229c the Docker host or a Docker container? Which container? I assumed it is the Docker container of service app of other.docker-compose.yml. Please comment if I'm missing something or misinterpreted your question and I will update my answer. Then I may explain in more detail or make another suggestion how to do service discovery between multiple Docker Compose projects.


Appendix

Cleanup

$ COMPOSE_PROJECT_NAME=other docker-compose -f other.docker-compose.yml down
$ COMPOSE_PROJECT_NAME=paymentservice docker-compose -f paymentservice.docker-compose.yml down

Versions

$ docker --version
Docker version 20.10.0, build 7287ab3
$ docker-compose --version
docker-compose version 1.26.0, build unknown
maiermic
  • 4,764
  • 6
  • 38
  • 77