【问题标题】:Docker Nginx + Node: address already in useDocker Nginx + Node:地址已在使用中
【发布时间】:2016-09-06 08:37:32
【问题描述】:

我正在尝试使用 Node.js(外部,在主机上)配置 Nginx(在 Docker 容器内)。 Nginx 配置使用upstreamproxy-pass 指令:

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;
    }
}

Node 应用程序侦听主机的 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 到 Node 应用程序 (-p 8080:8080),但是它给出了一个错误:Error starting userland proxy: listen tcp 0.0.0.0:8080: bind: address already in use.

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

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

$ wget 172.17.0.1:8080
Connecting to 172.17.0.1:8080... failed: Connection refused.

现在,我知道我可以 Dockerize 我的 Node 应用程序并在启动 Nginx 容器时使用 --link 参数,但这暂时不是解决方案,因为它需要大量重写 Node 应用程序。

非常感谢任何帮助。

【问题讨论】:

    标签: node.js nginx docker proxy reverse-proxy


    【解决方案1】:

    我首先建议您将 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 already in use,那是因为不止一项服务正在监听该地址。使用 netstat 或 lsof (linux|osx) 找出正在监听 8080 的进程。

    有关网络设置的一些额外信息。 https://docs.docker.com/engine/reference/run/#/network-settings

    【讨论】:

    • 好的,我试过使用--network host(有和没有-p 80:80等等,因为我猜这个选项端口声明是多余的)。如果我执行$ curl https://127.0.0.1,它会起作用,我会从 Node 应用程序获得响应,然而 Nginx 停止响应来自外部的请求(即,如果我从浏览器导航到 https://xxx.xxx.xxx.xxx)-.- 另一个有趣的问题是如果做$ curl https://localhost(而不是127.0.0.1),我会得到标准的“欢迎使用Nginx”页面o.O
    • 你的 nginx.conf 只监听 443,而不是 80。
    • 另外,您的 nginx 位于主机网络(本地主机、环回等)上,因此无法从您的计算机外部访问它。除非您尝试一些深奥的东西,否则我真的建议您遵循最佳实践。在私有桥接网络中运行您的容器,并且只将您的 nginx 暴露给外界。
    • 为了简洁起见,我从nginx.conf 中删除了端口 80 的部分 :) 我不是在尝试一些深奥的东西,开发一个应用程序然后每次都重新 dockerize 非常耗时我想测试一下。所以我想也许我应该对 Nginx 进行 docker 化,因为它不会改变并让我的 Node 应用程序保持原样(以便在开发的最后对其进行 docker 化)。感谢您的反馈!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 2017-07-07
    • 2020-10-06
    • 1970-01-01
    相关资源
    最近更新 更多