Justin
Justin

Reputation: 45320

How to network between multiple containers of the same image in docker-compose?

I am using docker-compose and my configuration file is simply:

version: '3.7'
volumes:
  mongodb_data: {}
services:
  mongodb:
    image: mongo:4.4.3
    restart: always
    ports:
      - "27017:27017"
    volumes:
      - mongodb_data:/data/db
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=super-secure-password
  rocket:
    build:
      context: .
    depends_on:
      - mongodb
    image: rocket:dev
    dns:
      - 1.1.1.1
      - 8.8.8.8
    volumes:
      - .:/var/rocket
    ports:
      - "30301-30309:30300"

I start MongoDB with docker-compose up, and then in new terminal windows run two Node.js application each with all the source code in /var/rocket with:

# 1st Node.js application
docker-compose run --service-ports rocket
# 2nd Node.js application
docker-compose run --service-ports rocket

The problem is that the 2nd Node.js application service needs to communicate with the 1st Node.js application service on port 30300. I was able to get this working by referencing the 1st Node.js application by the id of the Docker container:

Connect to 1st Node.js application service on: tcp://myapp_myapp_run_837785c85abb:30300 from the 2nd Node.js application service.

Obviously this does not work long term as the container id changes every time I docker-compose up and down. Is there a standard way to do networking when you start multiple of the same container from docker-compose?

Upvotes: 1

Views: 827

Answers (2)

David Maze
David Maze

Reputation: 158647

You can run the same image multiple times in the same docker-compose.yml file:

version: '3.7'
services:
  mongodb: { ... }
  rocket1:
    build: .
    depends_on:
      - mongodb
    ports:
      - "30301:30300"
  rocket2:
    build: .
    depends_on:
      - mongodb
    ports:
      - "30302:30300"

As described in Networking in Compose, the containers can communicate using their respective service names and their "normal" port numbers, like rocket1:30300; any ports: are ignored for this. You shouldn't need to manually docker-compose run anything.

Upvotes: 1

ruohola
ruohola

Reputation: 24018

Well you could always give specific names to your two Node containers:

$ docker-compose run --name rocket1 --service-ports rocket
$ docker-compose run --name rocket2 --service-ports rocket

And then use:

tcp://rocket1:30300

Upvotes: 0

Related Questions