[英]Docker container with nodejs app(NestJS) is not accessible from both other containers or host
I have an application, that consists of few docker containers: nginx, client, admin, backend and mongo.我有一个应用程序,它由几个 docker 容器组成:nginx、客户端、管理员、后端和 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.在容器中“后端”在端口 5000 上运行 NestJS 应用程序。容器暴露了端口 5000。但是容器没有响应任何请求,容器内的应用程序也没有收到它们。 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.
我什至尝试将端口 5000 暴露给我的本地机器,这样我就可以在 docker-host 之外发出请求,但是这样容器也不会响应。 When I'm running this NestJS app locally on my machine everything works perfectly.
当我在我的机器上本地运行这个 NestJS 应用程序时,一切正常。 I have nginx.conf to configure behavior nginx container.
我有 nginx.conf 来配置行为 nginx 容器。 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.
托管 NextJS 应用程序和侦听特定端口。 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
我对“后端”容器使用了相同的方法,但即使 nginx 似乎发出了正确的请求,它也没有收到响应,或者由于某种原因它向 docker-host 内部的错误地址发出请求
Dockerfile for my custom images: Dockerfile 用于我的自定义图像:
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: 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: 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;
}
}
With Fastify, what worked for me was:使用 Fastify,对我有用的是:
app.listen(3000, "0.0.0.0")
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.为避免答案在评论中丢失:使用 Docker 网络和链接的设置看起来是正确的,所以这似乎是过程本身的问题。
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.在nest.js 进程的启动中,绑定到与
localhost
或127.0.0.1
不同的接口很重要,因为Docker 创建虚拟网络接口并使用这些接口与进程通信。 So even if localhost
works when running on the host machine directly, this won't work for Docker networking.因此,即使
localhost
直接在主机上运行时工作,这也不适用于 Docker 网络。 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");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.