nginx - 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 配置文件中的块的目的是什么?
解决方案
一次只有一个应用程序可以绑定/侦听给定端口。
您启动了在端口 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 登录流没有问题。
推荐阅读
- php - Laravel Passport 没有 Vue 组件文件
- node.js - Socket.io 与 Firebase 主机上的客户端和 Heroku 上的服务器
- c# - Jenkins Freestyle 构建中 MSbuild 中的解决方案路径错误
- ruby-on-rails - 更改前面没有属性名称的验证消息
- java - 为什么 PrintWriter.println() 在写入 HTML 时不终止行?
- esp32 - 如何让 ESP32 与 Google 表通信
- javascript - 如何从一系列在 javascript 中充当行和列的数组中找到所有排列?
- c++ - 更改对象向量的对象时,值会不断重置
- selenium-webdriver - 在 Protractor 和 Selenium webdriver 中,如何获取已复制到剪贴板的文本?
- csv - csv 阅读器发现的行数少于 bufio 扫描仪