• 특정 경로만 백엔드로 보내는 거 궁금해요

    아직 서버나 리버스 프록시 같은 건 많이 접해보지 않아서요.
    이전에 간단하게 Nginx를 써봤는데, 전체 요청을 다른 서버로 보내는 건 어떻게 하는 건지 개념은 잡았거든요.

    근데 이게, '사이트 주소 중 특정 폴더로 들어오는 요청만' 따로 분리해서 내부 개발 서버 같은 곳으로 보내고 싶을 때가 생길 것 같아서요.
    예를 들어, 'example.com/api/v2'로 들어오는 요청만 A 서버로 보내고, 나머지는 평소처럼 처리하고 싶을 때요.

    이럴 때 Nginx 설정에서 어떤 부분을 건드려야 하는 건지, 초보자도 이해하기 쉽게 단계별로 설명해 주실 분 계실까요?
    어떤 지시어(directive)를 사용해야 하는지, 예시 코드랑 같이 보면 정말 좋을 것 같아요.

  • 안녕하세요, 질문 글 잘 읽어봤어요.
    이런 시나리오는 백엔드 아키텍처를 짜다 보면 정말 많이 부딪히는 부분이라, 궁금해하시는 게 당연해요.
    Nginx를 이용해서 '특정 경로(Prefix)'로 들어오는 요청만 다른 백엔드 서버(A 서버)로 보내고, 나머지 요청은 기존 로직(예: 웹 서버 또는 다른 서비스)으로 처리하는 건, 사실 Nginx의 핵심 기능 중 하나인 location 블록proxy_pass 지시어를 조합해서 사용하면 아주 깔끔하게 구현할 수 있습니다.
    초보자도 이해하기 쉽도록, 개념 설명부터 단계별 설정 방법, 그리고 실제 사용 시 유의사항까지 최대한 자세하게 설명해 드릴게요.
    --- ### 💡 1.
    기본 개념 정리: 왜 이게 필요한가요?
    우선 왜 이런 구성을 쓰는지 개념부터 잡고 가시는 게 중요해요.
    우리가 보통 example.com이라는 도메인을 가지고 있다고 가정해 봅시다.
    1.
    / (루트 경로): 이건 보통 웹사이트의 메인 페이지(HTML, CSS, JS 파일 같은 정적 파일이나, 첫 요청을 받는 웹 프레임워크)가 처리하는 영역이에요.
    2.
    /api/v2: 이 경로는 순수하게 API 호출 전용으로, 말씀하신 것처럼 별도의 백엔드 서비스(A 서버)가 전담하는 게 효율적이죠.
    3.
    /admin: 이건 관리자 페이지처럼 또 다른 별도의 서버(B 서버)가 처리할 수도 있고요.
    이 세 가지를 하나의 Nginx 뒤에 두고, "들어온 주소(URL)가 어디까지 일치하는가?"에 따라 "어떤 서버에게 전달할지"를 라우팅 해주는 게 바로 Nginx의 역할입니다.
    핵심 키워드는 location 블록입니다.
    location 블록은 Nginx에게 "만약 요청 URL이 이 패턴과 일치하면, 이 블록 안에 적힌 설정을 따라라"라고 알려주는 규칙 집합이에요.
    --- ### ⚙️ 2.
    핵심 지시어 조합: location + proxy_pass 말씀하신 요구사항을 구현하는 데 필요한 주요 지시어는 딱 두 가지입니다.

    A.

    location (위치 지정) 어떤 URL 패턴을 잡을지 지정합니다.

    • 문법: location /패턴 { ... } * 패턴 매칭: Nginx는 이 패턴을 매우 정교하게 매칭합니다.
    • =: 정확히 이 문자열과 일치할 때 (가장 엄격함).
    • ^~: 정규식보다 먼저 매칭되며, 이 패턴에 걸리면 다른 정규식 검사는 무시됩니다.
      (실무에서 많이 사용) * ~: 정규식으로 매칭합니다.
      (가장 유연하지만, 정규식 문법을 알아야 함) * (참고: 패턴을 생략하면 기본적으로 /와 같은 기본 매칭 규칙을 따릅니다.) #### B.
      proxy_pass (실제 전달) 요청을 받아 처리할 실제 백엔드 서버의 주소를 지정합니다.
    • 문법: proxy_pass http://[서버 주소]:[포트]; * 역할: Nginx가 요청을 가로채서, 지정된 주소로 마치 클라이언트가 직접 접속한 것처럼 요청을 전달해 줍니다.
      --- ### 💻 3.
      단계별 설정 예시 코드 (실습용) 가장 일반적이고 안전한 시나리오를 가정하고 코드를 작성해 드릴게요.
      가정 상황: 1.
      example.com으로 접속하는 모든 요청이 Nginx를 거칩니다.

    example.com/api/v2로 들어오는 요청만 A 서버(http://192.168.1.100:8080)로 전달해야 합니다.
    3.
    나머지 모든 요청 (예: /, /assets/, /images/)은 기존 웹 서버(http://127.0.0.1:80)가 처리해야 합니다.
    Nginx 설정 파일 (/etc/nginx/sites-available/example.conf 등)에 추가할 내용: ```nginx server { listen 80; server_name example.com; # 1.
    [특정 경로 전용] API 요청 처리 블록 (가장 먼저 검사되어야 함) # 'location /api/v2'는 'location /api/v2/' 또는 'location /api/v2' 일치 시 작동합니다.
    location /api/v2/ { # A 서버로 요청을 전달합니다.

    주의: URI를 그대로 전달하는 것이 핵심입니다.

    proxy_pass http://192.168.1.100:8080; # 실무에서 매우 중요한 헤더 설정들 (나중에 설명) proxy_set_header Host $host; 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 $scheme; } # 2.
    [나머지 모든 요청] 기본 웹 서버 처리 블록 (Fallback) # 이 블록은 위에 매칭되지 않은 모든 요청을 받습니다.
    location / { # 기존 웹 서버로 전달합니다.
    proxy_pass http://127.0.0.1:80; # 헤더 설정은 여기에도 필요합니다.
    proxy_set_header Host $host; 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 $scheme; } # (추가 팁: 만약 파일 요청(Static File)이 많다면, 아래처럼 별도 처리하는 게 성능상 더 좋을 수 있습니다.) # location ~* .(jpg|jpeg|png|gif|css|js)$ { # root /var/www/html/static; # expires 30d; # 캐싱 설정 예시 # } } ``` --- ### 🧐 4.
    초보자가 반드시 알아야 할 실무 팁과 주의점 (⭐️중요⭐️) 여기서 멈추면 안 돼요.
    실제 운영 환경에서는 이 설정 하나만으로는 부족하고, 아래의 몇 가지 디테일을 꼭 체크하셔야 합니다.

    💡 팁 1: URI 경로 처리 방식의 차이 (가장 많이 실수하는 부분) proxy_pass를 사용할 때, 백엔드 서버가 실제로 받을 URI 경로가 어떻게 처리되는지 이해해야 해요.

    **Case A: location /api/v2/ 와 같이 슬래시(/)로 끝내는 경우 (권장 방식) nginx location /api/v2/ { proxy_pass http://backend_a:8080/; # 뒤에 슬래시를 붙이는 것이 중요! } 만약 클라이언트가 example.com/api/v2/users로 요청하면, Nginx는 /api/v2/를 매칭하고, 뒤의 /users 부분만 잘라서 http://backend_a:8080/users로 보내줍니다.
    (Prefix 매칭 후 나머지 전달) Case B: location /api/v2 로 끝내고 슬래시가 없는 경우 (주의 필요) nginx location /api/v2 { proxy_pass http://backend_a:8080; # 뒤에 슬래시 없음 } 이 경우, Nginx는 전체 매칭된 URI를 통째로 전달하는 경향이 있어요.
    즉, 클라이언트가 example.com/api/v2/users로 요청하면, A 서버는 http://backend_a:8080/api/v2/users로 받게 됩니다.
    (전체 경로 유지) > ✅ 실전 가이드: 만약 A 서버가 오직 /users 같은 경로만 기대하고, /api/v2라는 접두사는 아예 모르고 있다면, Case A (location 뒤에 슬래시를 붙이고, proxy_pass 뒤에도 슬래시를 붙여서 경로를 잘라내는 방식)를 사용하는 것이 가장 안전하고 일반적입니다.

    💡 팁 2: 필수 헤더 설정 (Headering) 단순히 요청을 전달하는 것만으로는 부족합니다.

    백엔드 서버(A 서버)는 "이 요청이 정말 나에게 온 건가?", "실제 클라이언트의 IP는 뭐지?" 같은 메타데이터가 필요해요.
    이때 사용하는 것이 **proxy_set_header**입니다.

    • proxy_set_header Host $host;: 이 헤더는 백엔드 서버가 example.com으로 요청했다고 인식하게 해줍니다.
      (필수) * proxy_set_header X-Real-IP $remote_addr;: 실제 요청을 보낸 클라이언트의 IP 주소를 전달합니다.
    • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;: 프록시를 거치는 과정에서 여러 IP가 추가될 수 있으므로, 체인(Chain)을 기록해주는 것이 좋습니다.
      이 헤더들을 안 넣으면, A 서버가 요청의 출처를 잘못 판단하거나, 기대했던 호스트 이름으로 요청을 처리하지 못할 수 있습니다.

    💡 팁 3: Fallback과 우선순위 (Location의 매칭 순서) Nginx는 location 블록을 처리할 때 순서가 있습니다.

    가장 구체적인 매칭 (Exact Match): =으로 시작하는 것이 가장 우선순위가 높습니다.
    2.
    정규식 매칭: ^~ (Prefix Match)이 그 다음으로 우선순위가 높습니다.
    3.
    기본 매칭 (Regex): ~ (Regex Match)가 그다음입니다.
    4.
    나머지 (Fallback): location / 이 모든 것을 받습니다.
    따라서, 가장 특수한 규칙(API 요청 등)은 반드시 location /api/v2/ { ... }처럼 가장 상단에, 그리고 가장 구체적인 패턴으로 정의해 주셔야 합니다. 그렇지 않으면 아래의 location / 규칙에 먼저 걸려서 API 요청까지도 웹 서버로 보내버릴 수 있습니다.
    --- ### 📝 최종 정리 및 추천 체크리스트 요약하자면, 질문자님이 원하시는 구조는 **"Prefix 기반의 라우팅"**이며, 구현에 필요한 핵심은 locationproxy_pass의 조합입니다.
    1.
    우선순위: 가장 구체적이고 중요한 API 라우트부터 location 블록을 정의하세요.
    2.
    경로 분리: API 요청은 location /api/v2/ { proxy_pass http://A_SERVER/; } 형태로 분리하세요.
    3.
    기본 처리: 나머지 요청은 location / { proxy_pass http://WEB_SERVER/; } 형태로 처리하세요.
    4.
    필수 항목: proxy_set_header를 사용하여 호스트 정보와 실제 IP를 반드시 전달해 주세요.
    5.
    재로드: 설정 변경 후에는 sudo nginx -t로 문법 검사 후, sudo systemctl reload nginx (또는 service nginx reload)로 반드시 리로드해야 적용됩니다.
    이 가이드가 개념 잡는 데 큰 도움이 되었으면 좋겠습니다.
    이거 막상 설정할 때는 지시어 하나하나가 생소해서 막막할 수 있으니, 처음에는 A 서버 주소만 임시로 적어두고, '어떤 요청이 들어왔을 때, 이 블록이 실행되고, 이 헤더들이 전달되는지' 흐름만 그리면서 테스트해보시는 걸 추천드립니다.
    궁금한 점 있으면 또 질문 주세요!