Node.js Docker Nginx+;节点:地址已在使用中

Node.js Docker Nginx+;节点:地址已在使用中,node.js,nginx,docker,proxy,reverse-proxy,Node.js,Nginx,Docker,Proxy,Reverse Proxy,我正在尝试使用Node.js(外部,主机上)配置Nginx(内部Docker容器)。Nginx配置使用上游和代理传递指令: upstream helloworld { server localhost:8080; } server { listen 443; ssl on; ssl_certificate /some/cert.crt; ssl_certificate_key /some/cert.key; location / {

我正在尝试使用Node.js(外部,主机上)配置Nginx(内部Docker容器)。Nginx配置使用
上游
代理传递
指令:

upstream helloworld {
    server localhost:8080;
}

server {
    listen 443;
    ssl on;
    ssl_certificate /some/cert.crt;
    ssl_certificate_key /some/cert.key;
    location / {
        proxy_pass http://helloworld;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}
节点应用程序侦听主机的端口8080。现在,我启动Nginx容器

docker run \
        -d \
        -p 80:80 \
        -p 443:443 \
        -p 8080:8080 \
        -v /some/mounts:/to/some/mounts \
        --name nginx \
        nginx:alpine
我所期望的是,Nginx接收到端口80和443的连接,并将它们转发到其容器内的端口8080,然后将其转发到主机的端口8080到节点应用程序(
-p 8080:8080
),但是,它给出了一个错误:
启动userland代理时出错:侦听tcp 0.0.0.0:8080:bind:address已在使用。

我尝试将
localhost
更改为
127.0.0.1
,甚至更改为主机的ip地址(
172.17.0.1
,由Nginx容器内部的
$/sbin/ip route
生成),但似乎都不起作用。如果在启动容器时不使用
-p8080:8080
,它也不会工作

即使
172.17.0.1
是主机的ip地址,我也无法从Nginx容器中连接到它:

$ wget 172.17.0.1:8080
Connecting to 172.17.0.1:8080... failed: Connection refused.
现在,我知道在启动Nginx容器时,我可以将我的节点应用程序Dockerize并使用
--link
参数,但目前这不是一个解决方案,因为它需要大量重新编写节点应用程序


非常感谢您的帮助。

我首先建议您将nodejs应用程序移动到与nginx位于同一网络(网桥网络)上的容器中。它使它更容易/更安全(隔离nginx公共代理后面的节点)

否则,请在主机网络上运行nginx,使其
localhost
与主机相同

docker run \
    -d \
    -p 80:80 \
    -p 443:443 \
    -p 8080:8080 \
    -v /some/mounts:/to/some/mounts \
    --name nginx \
    --network host \
    nginx:alpine
如果您仍然得到一个已在使用的
bind:address
,那是因为不止一个服务正在侦听该地址。使用netstat或lsof(linux | osx)来确定哪个进程正在侦听8080


关于网络设置的一些额外信息

好的,我试过使用
--networkhost
(有和没有
-p80:80
等等,因为我猜使用这个选项端口声明是多余的)。如果我这样做,
$curlhttps://127.0.0.1
,它可以工作,我从节点应用程序获得响应,但是Nginx停止响应外部请求(即,如果我导航到
https://xxx.xxx.xxx.xxx
从浏览器)-另一个有趣的问题是如果执行
$curlhttps://localhost
(而不是
127.0.0.1
),我得到了标准的“欢迎使用Nginx”页面o.OYour Nginx.conf只侦听443,而不是80。此外,您的Nginx位于主机网络(localhost、loopback等)上,因此无法从计算机外部访问。除非你在尝试一些深奥的东西,否则我真的建议你遵循最佳实践。在专用网桥网络中运行您的容器,只将您的nginx暴露给外部世界。为了简洁起见,我从
nginx.conf
:)中删除了端口为80的部分。我不是在尝试一些深奥的东西,只是开发一个应用程序,然后每次想测试它时都将其重新归档非常耗时。所以我想也许我应该对Nginx进行dockerize,因为它不会改变并且保持我的节点应用程序不变(以便在开发的最后对其进行dockerize)。谢谢你的反馈!