skip to Main Content

I have an application, that consists of few docker containers: nginx, client, admin, backend and mongo.

In container "backend" is running NestJS application on port 5000. Container has exposed port 5000. But container is not responding to any requests and application inside of container doesn’t receive them. I’ve even tried to expose port 5000 to my local machine so I could make request outside of docker-host but this way container doesn’t respond as well. When I’m running this NestJS app locally on my machine everything works perfectly. I have nginx.conf to configure behavior nginx container. It should redirect certain requests to specific containers using proxy. This approach works fine for client and admin containers. Both hosting NextJS application and listening on specific port. I’ve used the same approach for "backend" container but even though nginx seems to make correct requests, it doesn’t receive response or for some reason it makes requests to wrong address inside of docker-host

Dockerfile for my custom images:

FROM node:14.15.4 as client
WORKDIR /usr/src/app
COPY /src/client/package*.json ./
RUN npm install
COPY /src/client .
EXPOSE 3000
CMD ["npm", "run", "dev"]

FROM node:14.15.4 as admin
WORKDIR /usr/src/app
COPY /src/admin/package*.json ./
RUN npm install
COPY /src/admin .
EXPOSE 3001
CMD ["npm", "run", "dev"]

FROM node:14.15.4 as backend
WORKDIR /usr/src/app
COPY /src/app/package*.json ./
RUN npm install
COPY /src/app .
EXPOSE 5000
CMD ["npm", "run", "start:dev"]

docker-compose.yml:

version: '3'
services:
  nginx:
    image: nginx:${NGNIX_VERSION}
    depends_on:
      - client
      - admin
    links:
      - client:client
      - admin:admin
      - backend:backend
    restart: on-failure:30
    volumes:
      - ./deploy/shared/config/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
    env_file:
      - .env
    networks:
      - default
    expose:
      - 80
    ports:
      - ${NGINX_BIND_PORT}:80
  mongo:
    image: mongo:${MONGO_VERSION}
    env_file:
      - .env
    networks:
      - default
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD}
  client:
    build:
      context: .
      target: client
    networks:
      - default
    volumes:
    - ./src/client:/usr/src/app
  admin:
    build:
      context: .
      target: admin
    networks:
      - default
    volumes:
    - ./src/admin:/usr/src/app
  backend:
    build:
      context: .
      target: backend
    networks:
      - default
    volumes:
    - ./src/app:/usr/src/app
    ports:
    - 5000:5000

networks:
  default:
    driver: bridge

nginx.conf:

upstream docker-client {
    server client:3000;
}

upstream docker-admin {
    server admin:3001;
}

upstream docker-backend {
    server backend:5000;
}

server {
    listen 80;
    server_name mr0bread.local;

    location / {
        proxy_pass http://docker-client;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_read_timeout 600s;
    }

    location /admin {
        proxy_pass http://docker-admin;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_read_timeout 600s;
    }

    location /backend {
            proxy_pass http://docker-backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_redirect off;
            proxy_read_timeout 600s;
        }
}

Here is the link to repo: GitHub

2

Answers


  1. To avoid the answer gets lost in the comments: The setup with Docker networks and linking looks correct, so this seemed to be an issue with the process itself.

    In the startup of the nest.js process, it is important to bind to a different interface than localhost or 127.0.0.1 because Docker creates virtual network interfaces and talks to the process using those. So even if localhost works when running on the host machine directly, this won’t work for Docker networking. This port would only be accessible from inside the container.

    So, instead of

    app.listen("localhost:3000");
    

    bind to all interfaces like this (using the corresponding port number of course):

    app.listen("0.0.0.0:3000");
    
    Login or Signup to reply.
  2. With Fastify, what worked for me was:

    app.listen(3000, "0.0.0.0")
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search