当通过Docker
我有一个超级简单的Node应用程序和一个Nginx配置,它充当Node应用程序的反向代理。如果我在本地运行Nginx(通过自制程序)和Node应用程序,一切正常。如果我在端口8080访问由Nginx配置定义的服务器,我将从节点应用程序获得输出,该应用程序在端口3000上运行。
我一直在尝试将这个简单的设置转换为使用Docker,并编写了以下Docker-compose文件:
version: '3.0'
services:
web:
build: .
ports:
- 3000:3000
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- 8080:8080
在运行docker-compose up
时,会构建映像,并且控制台中没有错误消息。访问localhost:3000
我收到Node应用程序的响应,但在访问localhost:8080
时,我收到一个Nginx 502错误页面,并在终端中出现以下错误:
连接到上游时连接失败(111:拒绝连接),客户端:172.18.0.1,服务器:localhost,请求:“GET / HTTP / 1.1”,上游:“http://127.0.0.1:3000/”,主机:“localhost:8080”
我的节点应用程序的Dockerfile如下所示:
FROM node:carbon
WORKDIR /app
ADD . /app
RUN npm install
CMD ["node", "."]
EXPOSE 3000
而Dockerfile.nginx看起来像这样:
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
并且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;
}
}
}
在启动Docker时,我可以看到Nginx正在端口8080上运行(因为我看到了502 Nginx页面),我可以看到节点应用正在运行(因为我可以在localhost:3000访问它)。我无法理解为什么我从nginx获得502。
我尝试过使用各种不同的东西,比如使用links
链接容器和depends_on
,但似乎没有任何区别。我也在使用docker-compose up --build
来确保每次进行更改时都不会缓存以前的版本。
编辑:似乎使它工作的东西是在docker-compose中添加一个container_name属性:
web:
container_name: nodeapp
build:
context: .
dockerfile: Dockerfile.node
ports:
- 3000:3000
然后在nginx.conf中的上游node_app配置中使用该容器名称:
upstream node_app {
server nodeapp:3000;
}
这对我没用?!
回答如下:问题是在您的Nginx配置中,您将Web服务的IP引用为127.0.0.1,这是运行docker容器的主机的环回地址。这可能会取决于您的设置(操作系统,防火墙)或可能不会。
正确的方法是使nginx
服务依赖于docker-compose.yml文件中的web
服务,并更新Nginx配置以通过名称(web
)而不是IP地址引用Web服务。 Here你可以找到更多关于docker compose的信息,具体取决于能力。
更新的docker-compose.yml文件将是:
version: '3.0'
services:
web:
build: .
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- 8080:8080
depends_on:
- web
请注意,我已经停止暴露web
服务的端口。您可能需要保留它来监控Web服务,但nginx
服务不需要它。
通过对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;
}
}
}
当通过Docker
我有一个超级简单的Node应用程序和一个Nginx配置,它充当Node应用程序的反向代理。如果我在本地运行Nginx(通过自制程序)和Node应用程序,一切正常。如果我在端口8080访问由Nginx配置定义的服务器,我将从节点应用程序获得输出,该应用程序在端口3000上运行。
我一直在尝试将这个简单的设置转换为使用Docker,并编写了以下Docker-compose文件:
version: '3.0'
services:
web:
build: .
ports:
- 3000:3000
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- 8080:8080
在运行docker-compose up
时,会构建映像,并且控制台中没有错误消息。访问localhost:3000
我收到Node应用程序的响应,但在访问localhost:8080
时,我收到一个Nginx 502错误页面,并在终端中出现以下错误:
连接到上游时连接失败(111:拒绝连接),客户端:172.18.0.1,服务器:localhost,请求:“GET / HTTP / 1.1”,上游:“http://127.0.0.1:3000/”,主机:“localhost:8080”
我的节点应用程序的Dockerfile如下所示:
FROM node:carbon
WORKDIR /app
ADD . /app
RUN npm install
CMD ["node", "."]
EXPOSE 3000
而Dockerfile.nginx看起来像这样:
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
并且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;
}
}
}
在启动Docker时,我可以看到Nginx正在端口8080上运行(因为我看到了502 Nginx页面),我可以看到节点应用正在运行(因为我可以在localhost:3000访问它)。我无法理解为什么我从nginx获得502。
我尝试过使用各种不同的东西,比如使用links
链接容器和depends_on
,但似乎没有任何区别。我也在使用docker-compose up --build
来确保每次进行更改时都不会缓存以前的版本。
编辑:似乎使它工作的东西是在docker-compose中添加一个container_name属性:
web:
container_name: nodeapp
build:
context: .
dockerfile: Dockerfile.node
ports:
- 3000:3000
然后在nginx.conf中的上游node_app配置中使用该容器名称:
upstream node_app {
server nodeapp:3000;
}
这对我没用?!
回答如下:问题是在您的Nginx配置中,您将Web服务的IP引用为127.0.0.1,这是运行docker容器的主机的环回地址。这可能会取决于您的设置(操作系统,防火墙)或可能不会。
正确的方法是使nginx
服务依赖于docker-compose.yml文件中的web
服务,并更新Nginx配置以通过名称(web
)而不是IP地址引用Web服务。 Here你可以找到更多关于docker compose的信息,具体取决于能力。
更新的docker-compose.yml文件将是:
version: '3.0'
services:
web:
build: .
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- 8080:8080
depends_on:
- web
请注意,我已经停止暴露web
服务的端口。您可能需要保留它来监控Web服务,但nginx
服务不需要它。
通过对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;
}
}
}