#nginx #port
Вопрос:
В macOS я обычно запускаю свой проект на локальном 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?
Ответ №1:
Только одно приложение может одновременно привязывать/прослушивать данный порт.
Вы запустили приложение, работающее на порту 443: sudo PORT=443 HTTPS=true ./node_modules/.bin/react-scripts start
Затем, когда вы попытались запустить nginx также на порту 443, это не удалось, потому что ваше приложение уже использует 443.
Чтобы исправить это:
- остановите nginx
- остановите свое приложение и перезапустите его, запустив на другом порту (например
3000
):sudo PORT=3000 HTTPS=true ./node_modules/.bin/react-scripts start
- отредактируйте свою конфигурацию nginx, чтобы сообщить nginx, что ваше приложение («вверх по течению») теперь работает на порту 3000.
proxy_pass https://localhost:3000;
- запустите nginx
Кроме того, я бы посоветовал вам завершить работу по протоколу SSL (https) в nginx и разрешить nginx небезопасно подключаться к вашему приложению на локальном хосте, чтобы уменьшить другие проблемы. В настоящее время похоже, что вы выполняете завершение ssl в nginx, а затем еще одно соединение/завершение 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 или что-то подобное, чтобы переключить порт, используемый вашим приложением в режиме разработки и производства. На самом деле нет никакой причины, по которой вам нужно использовать https/443 на локальном хосте во время разработки. Вы не сможете получить надежный сертификат SSL для локального хоста, поэтому его действительно нет point…it просто усложняет твою жизнь.
У меня нет проблем с тестированием потоков входа в систему oauth http://localhost:3000 например, с помощью Google.
Комментарии:
1. Может ли кто — нибудь сказать мне, какова цель блока
location / { ... }
в моем файле конфигурации nginx? Удаление этого, похоже, не повлияло на мои тесты.2. Блоки расположения сообщают nginx, как вы хотите обрабатывать различные запросы. например, отправлять запросы в /auth в одно место и в /foobar в другом месте или с другими правилами кэширования. Наиболее конкретный (регулярное выражение или самый длинный) соответствующий блок расположения «выигрывает», но см. Приоритет . В вашем случае у вас есть два блока регулярных выражений…
/auth
который идет на funfun (не domain…in ваш файл hosts или?) и/success
который перенаправляет. Все остальные запросы будут обрабатываться по/
местоположению, которое перенаправляет ваше приложение.3. «отредактируйте конфигурацию nginx, чтобы сообщить nginx, что ваше приложение («вверх по течению») сейчас работает на порту 3000 и небезопасно (измените https на http).» => У меня есть несколько >
proxy_pass
в моем файле, какой из них вы предлагаете заменитьproxy_pass http://localhost:3000;
?4. Я говорю о
proxy_pass
localhost
том, что у вас есть только одно, которое я могу видеть. Другой proxy_pass предназначен дляhttps://funfun/10studio/auth/...
, и я не уверен, что это должно делать, так как это не локальный хост и не является реальным доменом. Вы добавили что-то в свой файл hosts или что-то для сопоставленияfunfun
с реальным компьютером?5.
https://funfun/10studio/auth/...
имеет отношение кupstream funfun { server 178.62.87.72:443; }
.
Ответ №2:
Любой порт может быть привязан один раз к данному интерфейсу. Теперь, если вы запустите сервер приложений react, и он уже привязывает порт 443
к интерфейсу 0.0.0.0
, который в данном случае используется как своего рода подстановочный знак, означающий «прослушивание порта 443 на всех интерфейсах на моем компьютере», то любое другое приложение не сможет использовать этот порт, потому что он уже занят. В вашей конфигурации nginx вы можете увидеть строку, в которой говорится, что она также хочет использовать порт 443:
server {
listen 443 ssl; #<--- this is port config
server_name localhost;
У вас есть (по крайней мере) 2 варианта исправления этой ошибки:
- изменение
PORT=443
в локальном приложении - измените строку с номером порта в конфигурации nginx на любую другую, не занятую
Далее — location / { ... }
означает, что все запросы, начиная с /
которых фактически все запросы, кроме тех, которые были пойманы в двух предыдущих location
блоках, будут перенаправлены на другой веб-сервер, расположенный по https://localhost/
адресу, с некоторыми дополнительными заголовками. Это называется обратным прокси-сервером.
Комментарии:
1. Я не хочу вносить изменения
PORT=443
в свое приложение, потому что я хочу всегда запускать приложение (включая перенаправление) в разделеhttps://localhost/...
. Я попытался вставитьlisten 444 ssl;
файл конфигурации nginx. Nginx может быть запущен иhttps://localhost/#/start
работает. Однакоhttps://localhost/auth/...
перенаправить его, как и раньше, не удалось; Мне пришлось использоватьhttps://localhost:444/auth/...
для этого обратный прокси-сервер.2. Тогда да, это не сработало бы. Тем не менее ответ на ваш вопрос, почему это не работает, все еще остается в силе. Единственное, что я мог бы посоветовать, это изменить порт вашего приложения на другой, например
4433
, и изменить конфигурацию обратного прокси-сервера в nginx наproxy_pass https://localhost:4433/;