2

I'm using an API gateway (for now) with NestJS and a microservice (also with NestJS) in a Docker container. The plan is to have the gateway communication with any containable microservice I configure, but I'm having a hard time establishing this connection.

  • If I deploy both projects (gateway and microservice) without containers, they communicate successfully;
  • If the gateway is inside a container, it won't find the service because it is looking for it at 'localhost' and not the container host (I'll look into this later, even though I'm not sure how to solve it just yet);
  • If the gateway is deployed locally and the microservice is inside a container, I can't seem to communicate with it, it always gives me a timeout.

This last point is the problem I'm trying to address here. After a lot of experiments I can't seem to make this work at all, and it looks to be a pretty trivial thing. Here's my code:

Gateway modules configuration:

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'trips-svc',
        transport: Transport.TCP,
        options: {
          host: '127.0.0.1',
          port: 3002,
        },
      },
    ]),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Gateway docker-compose

version: "3.7"

services:
  gateway:
    build:
      context: .
      target: development
    networks:
      - web-gate-net
    volumes:
      - .:/usr/src/web-gate
      - /usr/src/web-gate/node_modules
    expose:
      - 5001
    ports:
      - 5001:5001
    command: npm run start:dev
    restart: "on-failure"

networks:
  web-gate-net:

(the Dockerfile associated with this project simply builds the application and runs node dist/main)

Microservice docker-compose

version: "3.7"

services:

  service:
    build:
      context: .
      target: development
      network: host
    volumes:
      - .:/usr/src/trips-svc
      - /usr/src/trips-svc/node_modules
    expose:
      - ${SERVICE_PORT}
    ports:
      - ${SERVICE_PORT}:${SERVICE_PORT}
    command: npm run start:dev
    restart: "on-failure"

(SERVICE_PORT is set on an .env file as 3002)

I've done some experiments with these configurations (using the expose keyword, the ports keyword, both...), but this is the configuration as-is. I'm relatively new to networks, so I'm not sure what's wrong here, but I'm fairly certain this has to do with my networking configurations, and since it's a rather specific issue, I can't seem to find any documentation that helps.

If anyone could give me any pointers, I'd be much appreciated.

Thanks.

gilneto8
  • 222
  • 1
  • 3
  • 12
  • shouldn't you put both in same network ? – Madhawa Priyashantha Jan 15 '21 at 12:20
  • I can only make that work if I set both the gateway and the microservice(s) with `network_mode: host`. If I try to specify the networks individually, even if they are in a common network, the cases above apply. If I specify `network_mode`, I can't specify `networks`, and I don't want all services to have access to each other (if possible). – gilneto8 Jan 15 '21 at 12:37
  • Does [From inside of a Docker container, how do I connect to the localhost of the machine?](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach) address your issue, as you note, in Docker, `localhost` is usually the container itself but that question describes how to call back to the host. If both components are in the same Compose file, [Networking in Compose](https://docs.docker.com/compose/networking/) in the Docker documentation describes the host names that are available. – David Maze Jan 15 '21 at 12:52

1 Answers1

0

If you want to have both your gateway and service running in a different container:

Your gateway's docker-compose ports line should look like this: 3002:5001. This will expose your 3002 port as 5002 for anything outside the container. You should remove the expose and networks (in your service and at the end of your file) lines with what's nested in it.

As for your micro-service's docker-compose remove also the network and expose lines.

In your gateway you should replace localhost with service when calling from your container. Same from inside your service container, replace localhost with gateway. This is because docker has its own network and the names are simply the one you set after services in your docker-compose files.

HartWoom
  • 537
  • 1
  • 7
  • 18