skip to Main Content

I am trying to set up multiservices architecture in my Node.js backend with docker. I have currently two services with two separate databases

version: "3"
services:
  server-api-getaway:
    build:
      context: "."
      dockerfile: "./server-api-gateway/Dockerfile"
    depends_on:
      - db
      - redis
    ports:
      - "7100:7100"
    volumes:
      - ./server-api-gateway:/usr/src/app/server-api-gateway
    environment:
      - CHOKIDAR_USEPOLLING=true
      - REDIS_URL=redis://cache
      - DATABASE_URL=postgres://postgres:postgres@db:3336/dbname
      - DATABASE_PORT=3336
      - DATABASE_HOST=host.docker.internal
      - POSTGRES_DB=dbname
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - PORT=7100

  db:
    image: postgres
    restart: always
    environment:
      - POSTGRES_DB=dbname
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - "3336:3306"

  server-user-service:
    build:
      context: "."
      dockerfile: "./server-user-service/Dockerfile"
    depends_on:
      - user-service-db
    ports:
      - "7000:7000"
    volumes:
      - ./server-user-service:/usr/src/app/server-user-service
    environment:
      - CHOKIDAR_USEPOLLING=true
      - REDIS_URL=redis://cache
      - DATABASE_URL=postgres://postgres:postgres@user-service-db:3307/dbname
      - DATABASE_PORT=3307
      - DATABASE_HOST=host.docker.internal
      - POSTGRES_DB=dbname
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - PORT=7000

  user-service-db:
    image: postgres
    restart: always
    environment:
      - POSTGRES_DB=dbname
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - "3307:3306"

  redis:
    image: redis
    container_name: cache
    restart: always
    ports:
      - 6379:6379

volumes:
  pgdata:
    driver: local
  pgconf:
    driver: local
  pglog:
    driver: local

I expect both databases to run on different ports, but when I run docker-compose up they are exposed to 5432 port

2021-03-05 07:12:10.111 UTC [1] LOG: listening on IPv4 address
"0.0.0.0", port 5432

When I connect my service to port 5432 everything works fine. But I need two databases to be exposed to different ports. How can I achieve it?

Update

I’ve changed port mapping as was suggested in comments.

  user-service-db:
    image: postgres
    restart: always
    environment:
      - POSTGRES_DB=dbname
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - "5432:3336"

And made a fresh start after docker-compose down

Result remained the same

user-service-db_1 | 2021-03-05 10:01:23.023 UTC [1] LOG:
listening on IPv4 address "0.0.0.0", port 5432

probably there is a detail I am missing

2

Answers


  1. You need to expose the correct port.
    Postgres default port is 5432: i.e. the postgres service in your docker container will listen to port 5432.
    I guess, on the host, you want to listen 3336 (or 3306?).

    in this case the mapping must be:

    ports:
      - "3336:5432"
    

    i.e. the format is HOST:CONTAINER

    see also:

    Login or Signup to reply.
  2. As an implementation detail, containers have their own private IP addresses. You can’t usually access these addresses from outside Docker, but when your container tries to connect to the host name db, that maps to one of these internal addresses. This means that it’s okay for processes in different containers to listen on the same port, since each process is in its own isolated network space.

    That means it’s standard for a packaged process to listen on its "normal" port. The output you’re seeing is the output of the PostgreSQL startup; this will always listen on 0.0.0.0:5432 (unless you make tricky modifications to its configuration file).

    Connections between containers also always connect to the "normal" port:

     # Use ordinary port, ports: are ignored       vvvv
    - DATABASE_URL=postgres://postgres:postgres@db:5432/dbname
    

    Publishing a port makes it accessible from outside Docker, using the host’s IP address (and DNS name). The second ports: number needs to match the port number inside the container, the first one can be anything that’s not already in use. Connections between containers never use this.

    ports:
      #       vvvv the ordinary port, fixed by the image
      - "3336:5432"
    

    "Expose" as a verb means almost nothing in modern Docker. EXPOSE in a Dockerfile is mostly documentation and there’s no reason to use the Compose expose: setting.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search