Search code examples
dockerdocker-composemicroservices

How to best handle shared services using docker-compose for local development in microservice architecture?


Trying to set up an effective pattern that allows communication between all of my services and allows for local development on multiple services simultaneously. I am currently setting up local development for my application using docker compose. The basic idea of my docker-compose.yml looks something like this.

version: '3'
services:
  web: 
    <web_config>
  worker:
    <worker_config>
  service-a:

I'm questioning how to handle service-a.

service-a is required by any local applications I am running. So if I am running this application and another at the same time, they will both need to communicate with service-a.

Should service-a be running in its own compose instance? If so, are networks the best way for all my apps to communicate with service-a? From my understanding, this used to be the job of links, but networks are now preferred. I have already tried running with network_mode host, but am running into issues, as I am using Docker for Mac.

I've seen a lot of opinions and solutions out there, but I'm honestly unsure which of these approaches is best. Some of the solutions I've seen include:

  • creating a shared network for all my services and run them separately in their own docker composes
  • using network_mode: 'host' and run everything on my host (Sadly I couldn't get this working)
  • running a separate compose of all my shared services that all other services depend on

Let me know if you've run into this and have any advice to share, thanks!


Solution

  • Each docker-compose stands up its own network for the services it manages. As you proposed, using a shared bridge network would be the easiest way to ensure each different stack of services in separate docker-compose.yml would be able to connect to one another.

    You can tell docker-compose to look for and use a pre-existing network. You can create this network with docker network create or maybe specify it in your service-a docker-compose.yml as a custom network with a static name:

    service-a docker-compose.yml

    version: '3'
    services:
      service-a:
        ...
    
    networks:
      mynetwork:
        driver: bridge
    

    Then use that network in your other docker-compose.yml files. You need to specify the network at the top level of the docker-compose.yml and then you can tell each service to use it:

    some other docker-compose.yml

    version: '3'
    services:
      web:
        ...
      networks:
        - mynetwork
    
    networks:
      mynetwork:
        external:
          name: mynetwork
    

    I only suggest the second option since you said any other app would need service-a running anyway.