首页 > 解决方案 > Nginx 与在 443 上运行的应用程序发生冲突

问题描述

在 MacOS 中,我通常在 localhost 中运行我的项目sudo PORT=443 HTTPS=true ./node_modules/.bin/react-scripts start。结果,https://localhost/#/start在浏览器中工作。

现在,要在 localhost 中运行第三方身份验证,我需要运行 nginx。这是我的/usr/local/etc/nginx/nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream funfun {
        server 178.62.87.72:443;
    }

    server {
        listen              443 ssl;
        server_name localhost;
        ssl_certificate /etc/ssl/localhost/localhost.crt;
        ssl_certificate_key /etc/ssl/localhost/localhost.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_session_timeout 1d;
        ssl_stapling off;
        ssl_stapling_verify off;
        add_header Strict-Transport-Security max-age=15768000;
        add_header X-Frame-Options "";
        proxy_ssl_name "www.funfun.io";
        proxy_ssl_server_name on;

        location ~ /socialLoginSuccess {
            rewrite ^ '/#/socialLoginSuccess' redirect;
        }

        location ~ /auth/(.*) {
            proxy_pass  https://funfun/10studio/auth/$1?$query_string;
            proxy_set_header Host localhost;
        }

        location / {
            proxy_set_header    Host                $host;
            proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
            proxy_set_header    X-Forwarded-Proto   $scheme;
            proxy_set_header    Accept-Encoding     "";
            proxy_set_header    Proxy               "";
            proxy_pass          https://localhost/;
            # These three lines added as per https://github.com/socketio/socket.io/issues/1942 to remove socketio error
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection "upgrade";
        }
    }
    include servers/*;
}

但是,启动 nginx 会返回以下错误:

$ sudo nginx
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:443 failed (48: Address already in use)
nginx: [emerg] still could not bind()

看来,nginx 已经与在 443 上运行的应用程序发生冲突。有人知道为什么吗?

另外,谁能告诉location / { ... }我 nginx 配置文件中的块的目的是什么?

标签: nginxport

解决方案


一次只有一个应用程序可以绑定/侦听给定端口。

您启动了在端口 443 上运行 的应用程序:sudo PORT=443 HTTPS=true ./node_modules/.bin/react-scripts start

然后,当您尝试在端口 443 上启动 nginx 时,它会失败,因为您的应用程序已经在使用 443。

要解决这个问题:

  • 停止 nginx
  • 停止您的应用程序并重新启动它在不同的端口上运行(例如3000):
    • sudo PORT=3000 HTTPS=true ./node_modules/.bin/react-scripts start
  • 编辑您的 nginx 配置以告诉 nginx 您的应用程序(“上游”)现在正在端口 3000 上运行。
    • proxy_pass https://localhost:3000;
  • 启动 nginx

此外,我建议您在 nginx 上执行 SSL (https) 终止,并让 nginx 不安全地连接到本地主机上的应用程序,以减少其他问题。目前,您似乎正在 nginx 上进行 ssl 终止,然后对您的应用程序/上游进行另一个 ssl 连接/终止。在本地主机上或通过安全/私有网络(例如在 AWS VPC 中)连接时,这实际上是没有必要的。

  • 停止 nginx
  • 停止您的应用程序并重新启动它在不同的端口上运行(例如3000):
    • HTTPS=true_sudo PORT=3000 HTTPS=true ./node_modules/.bin/react-scripts start
    • ...以及您的 React 应用中需要进行的任何其他更改以禁用 ssl/https。
  • 编辑您的 nginx 配置以告诉 nginx 您的应用程序(“上游”)现在在端口 3000 上运行并且不安全(将 https 更改为 http)。
    • proxy_pass http://localhost:3000;
  • 启动 nginx

对于生产,你真的应该总是在你的应用程序前面运行 nginx。这使您可以轻松地进行 ssl 终止、负载平衡(多个应用程序/上游)以及提供静态文件(jpg、css 等),而无需通过 nodejs 或其他应用程序服务器运行。它将更好地扩展。适合工作的正确工具。

出于本地开发目的,您可以针对本地不安全的 http://localhost:3000 工作。如果您出于某种原因真的讨厌使用端口 3000,那么您当然可以将 NODE_ENV 与 dotenv 或类似方法结合使用来更改应用程序在开发模式和生产模式下使用的端口。在开发期间确实没有任何理由需要在 localhost 上使用 https/443。您将无法为 localhost 获得受信任的 SSL 证书,因此真的没有任何意义……它只会让您的生活更加困难。

例如,我使用 google 针对 http://localhost:3000 测试 oauth 登录流没有问题。


推荐阅读