[英]Nginx can't find upstream node app when running via Docker-compose
I have a super simple Node app and an Nginx config which acts as a reverse proxy to the Node app.我有一个超级简单的 Node 应用程序和一个 Nginx 配置,它充当 Node 应用程序的反向代理。 Everything works fine if I run Nginx (via homebrew) and the Node app locally.
如果我在本地运行 Nginx(通过自制软件)和 Node 应用程序,一切正常。 If I visit the server defined by the Nginx config at port 8080 I get the output from the node app, which is running on port 3000.
如果我在端口 8080 访问由 Nginx 配置定义的服务器,我会从运行在端口 3000 上的节点应用程序获得 output。
I've been trying to convert this simple setup to use Docker and have written the following Docker-compose file:我一直在尝试将这个简单的设置转换为使用 Docker 并编写了以下 Docker-compose 文件:
version: '3.0'
services:
web:
build: .
ports:
- 3000:3000
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- 8080:8080
On running docker-compose up
the images are built and there are no error messages in the console.在运行
docker-compose up
,图像已构建并且控制台中没有错误消息。 On visiting localhost:3000
I get the response from the Node app but on visiting localhost:8080
I get an an Nginx 502 error page and the following error in the terminal:在访问
localhost:3000
时,我得到了 Node 应用程序的响应,但在访问localhost:8080
时,我得到一个 Nginx 502 错误页面和终端中的以下错误:
connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: " http://127.0.0.1:3000/ ", host: "localhost:8080"
connect() 连接到上游时失败(111:连接被拒绝),客户端:172.18.0.1,服务器:localhost,请求:“GET / HTTP/1.1”,上游:“ http://127.0.0.1:3000/ ”,主机:“本地主机:8080”
My Dockerfile for the node app looks like so:我的节点应用程序的 Dockerfile 如下所示:
FROM node:carbon
WORKDIR /app
ADD . /app
RUN npm install
CMD ["node", "."]
EXPOSE 3000
and the Dockerfile.nginx looks like so: Dockerfile.nginx 看起来像这样:
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
and the nginx.conf looks like so: nginx.conf 看起来像这样:
events {
worker_connections 1024;
}
http {
upstream node_app {
server 127.0.0.1:3000;
}
server_tokens off;
# Define the MIME types for files.
include mime.types;
default_type application/octet-stream;
# Speed up file transfers by using sendfile()
# TODO: Read up on this
sendfile on;
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://node_app;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
On starting Docker up I can see that Nginx is running on port 8080 (because I see the 502 Nginx page) and I can see that the node app is running (because I can visit it at localhost:3000). On starting Docker up I can see that Nginx is running on port 8080 (because I see the 502 Nginx page) and I can see that the node app is running (because I can visit it at localhost:3000). I can't work out why I get the 502 from nginx.
我不知道为什么我从 nginx 得到 502。
I've tried using various different things like using links
to link the containers and depends_on
but nothing seems to make any difference.我尝试过使用各种不同的东西,比如使用
links
来链接容器和depends_on
,但似乎没有任何区别。 I'm also using docker-compose up --build
to make sure I'm not caching previous builds each time I make a change.我还使用
docker-compose up --build
来确保每次进行更改时都不会缓存以前的构建。
EDIT: Something that seems to make it work is to add a container_name property in to the docker-compose:编辑:似乎使它起作用的是在 docker-compose 中添加一个 container_name 属性:
web:
container_name: nodeapp
build:
context: .
dockerfile: Dockerfile.node
ports:
- 3000:3000
and then using that container name in the upstream node_app config in nginx.conf:然后在 nginx.conf 的上游 node_app 配置中使用该容器名称:
upstream node_app {
server nodeapp:3000;
}
which makes no sense to me?!这对我来说没有意义?!
The problem is that in your Nginx configuration you are referencing the IP of the Web service as 127.0.0.1 which is the loopback address of the Host machine running the docker container. 问题在于,在您的Nginx配置中,您将Web服务的IP引用为127.0.0.1,这是运行docker容器的主机的环回地址。 This may work depending on your setup (OS, firewall) or may not.
这可能会起作用,具体取决于您的设置(操作系统,防火墙),也可能不起作用。
The correct way would be to make the nginx
service depends on the web
service in your docker-compose.yml file and update the Nginx config to reference the Web service by name ( web
) instead of by IP address. 正确的方法是使
nginx
服务依赖于docker-compose.yml文件中的web
服务,并更新Nginx配置以按名称( web
)而不是IP地址引用该Web服务。 Here you can find more info related to docker compose depends on capability. 在这里您可以找到与docker compose相关的更多信息,具体取决于功能。
The updated docker-compose.yml file would be: 更新后的docker-compose.yml文件为:
version: '3.0'
services:
web:
build: .
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- 8080:8080
depends_on:
- web
Notice that I have stop exposing the port of the web
service. 请注意,我已经停止公开
web
服务的端口。 May be you need to keep it to monitor the Web service but is not required for the nginx
service. 可能是您需要保留它以监视Web服务,但
nginx
服务不是必需的。
With this update to the docker-compose.yml file the Nginx config will be as follows: 通过对docker-compose.yml文件的此更新,Nginx配置将如下所示:
events {
worker_connections 1024;
}
http {
upstream node_app {
server web:3000;
}
server_tokens off;
# Define the MIME types for files.
include mime.types;
default_type application/octet-stream;
# Speed up file transfers by using sendfile()
# TODO: Read up on this
sendfile on;
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://node_app;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.