nginx Proxy_pass를 사용하여 경로를 제거하는 방법

nginx Proxy_pass를 사용하여 경로를 제거하는 방법

에서 실행 중인 웹 애플리케이션이 있고 의 http://example.com/별도 서버에 다른 애플리케이션을 "마운트"하고 싶습니다 http://example.com/en. 업스트림 서버가 proxy_pass작동하는 것 같지만 한 가지 문제가 있습니다.

upstream luscious {
 server lixxxx.members.linode.com:9001;
}

server {
  root /var/www/example.com/current/public/;
  server_name example.com;

  location /en {
    proxy_pass http://luscious;
  }
}

을 열 때 example.com/en업스트림 애플리케이션이 을 반환합니다 404 not found /en. 업스트림에는 경로가 없으므로 이는 의미가 있습니다 /en.

proxy_path올바른 솔루션 인가요 ? /en대신 루트 경로로 수신하도록 "업스트림"을 다시 작성해야 합니까 ? 아니면 업스트림으로 전달된 경로를 다시 작성할 수 있는 지시문이 있습니까?

답변1

이는 정규 표현식을 사용하지 않고 원하는 작업을 수행하는 가장 효율적인 방법일 것입니다.

location = /en {
    return 302 /en/;
}
location /en/ {
    proxy_pass http://luscious/;  # note the trailing slash here, it matters!
}

답변2

인기가 높아지고 있는 새로운 정규식 기반 답변을 다루고 싶습니다.

location ~ ^/en(/?)(.*)$ {  # OOPS!
  proxy_pass http://luscious/$2$is_args$args;  # OOPS!
}

이 솔루션은 언뜻 보면 더 귀엽게 보일 수 있지만 여러 가지 이유로 잘못된 것입니다.

  • 위의 정규식은 요청 URI와 일치하여 업스트림 /enjoy으로 리디렉션됩니다 /joy. 이게 정말 의도된 걸까요?

  • 요청은 /en리디렉션으로 이어지지 않으며 /업스트림에서 직접 서비스를 제공합니다(거의 요청이 /en/대신 이루어진 것처럼 보이지만 완전히는 아님). 루트 페이지 업스트림 내에서 상대 URI를 사용하는 경우(그렇지 않으면 왜 /en/업스트림 URI 내에 바로 접두어가 없겠습니까 ?), 예를 들어 src="style.css"(예를 들어 언어별 을 참조할 수 있음 url("menu.png")) 브라우저는 다음을 요청합니다. 대신 /style.css/en/style.css. (또는 어디에서나 절대 URI를 사용하더라도 상대적으로 모호한 세미선택적 리소스를 누군가 참조하면 어떻게 될까요?) 앗, 갑자기 사이트가 작동하지 않을 수 있지만 가끔 또는 극단적인 경우에만 작동합니다.

  • 내대로OP의 자체 답변에서 이미 언급한 다른 질문에 대한 이전 조언, 정규식을 사용하면proxy_redirect지시문에 따라 기본값이 default로 변경되었습니다 off. 즉, Location: http://127.0.0.1:8080/en/dir/요청이 /en/dir있을 때 업스트림이 응답하면 클라이언트가 이를 보게 되며 분명히 올바르게 작동하지 않을 것입니다. ( /en처음에 정규식 사용을 요청하는 요청 의 경우 특히 아이러니했을 것입니다 . 그러나 이 특정 구현은 대신 위에서 이미 언급한 것처럼 또 다른 문제로 어려움을 겪습니다.) 또한 이미upstream지시문을 사용하는 경우, 특히 업스트림 서버가 두 개 이상인 경우 사용자 지정 서버를 사용하려고 하면 더욱 추악해질 수 있습니다. proxy_redirect각 서버에 대해 어떻게 별도의 서버를 확보합니까? 내에서 정규식을 사용하여 proxy_redirect어떤 호스트와도 일치시킬 수도 있지만 나중에 도메인 간 리디렉션을 제공하기로 결정하면 어떻게 될까요?

단일 정규식 기반 위치로 위 사항 중 일부를 해결하기 위해 다음을 수행할 수 있습니다( 더 간단하게 만들기 위해 기반 지시문 proxy_pass에서 서버에 대한 참조도 삭제해야 했습니다 ).upstreamproxy_redirect

location ~ ^/en/?((?<=/).*)?$ {
  location = /en { return 302 /en/; }
  proxy_pass http://127.0.0.1:8080/$1$is_args$args;
  proxy_redirect http://127.0.0.1:8080/ /en/;
}

그래서 나에게 묻는다면,두 개의 형제 최상위 위치가 있는 원래 솔루션대신 정규식 경로를 사용하여 토끼 구멍에 빠지는 것보다 더 나은 아이디어가 될 것입니다.

답변3

그래서 내가 찾은 것은stackoverflow에 대한 답변:

upstream luscious {
 server lixxxx.members.linode.com:9001;
}

server {
  root /var/www/example.com/current/public/;
  server_name example.com;

  location ~ ^/en(/?)(.*) {
    proxy_pass http://luscious/$2;
  }
}

기본적으로: 정규식을 위치에 전달하고 역참조를 Proxy_pass URL에 전달합니다.

답변4

위에서 허용된 솔루션을 사용해 보았지만 모든 CSS 및 JS 자산에 대해 이상한 리디렉션이 발생하는 것으로 나타났습니다. 결국 저는 LinuxServer SWAG Nginx 구성이 수행되는 방식에서 영감을 얻었습니다. 당신은 그들을 찾을 수 있습니다여기. 보세요 pihole.subfolder.conf.sample.

따라서 내 솔루션은 다음과 같습니다.

location /en {
    return 302 $scheme://$host/en/;
}

location ^~ /en/ {
    set $upstream_app lixxxx.members.linode.com;
    set $upstream_port 9001;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    rewrite /en(.*) $1 break;
}

관련 정보