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
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
or127.0.0.1
because Docker creates virtual network interfaces and talks to the process using those. So even iflocalhost
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
bind to all interfaces like this (using the corresponding port number of course):
With Fastify, what worked for me was: