8. 경로 기반 라우팅(Path-based Routing)

박은서's avatar
May 01, 2026
8. 경로 기반 라우팅(Path-based Routing)

1. 경로 기반 라우팅(Path-based Routing)

1️⃣ Path-based Routing 개념

1) Path-based Routing이란?

  • URL의 경로(path) 를 기준으로 요청을 서로 다른 서버로 분기하는 방식
  • 하나의 도메인에서 여러 서비스를 나눠서 처리 가능
  • 예시
    • /app1 → app1 서버로 전달
    • /app2 → app2 서버로 전달

2) 핵심 구조

  • 클라이언트 → Nginx (리버스 프록시) → 내부 서버(app1, app2)
  • Nginx가 경로를 보고 어디로 보낼지 결정

3) 동작 흐름

  1. 사용자가 요청
    1. http://localhost/app1
  1. Nginx가 요청 받음
      • listen 80으로 대기 중
  1. location으로 경로 확인
    1. location /app1
  1. 해당 서버로 전달
    1. proxy_pass → app1 서버

4) 사용하는 이유

① 단일 진입점
  • 여러 서버를 하나의 주소로 통합
② 서비스 분리
  • 기능별로 서버 분리 가능
    • /api
    • /admin
    • /user
③ 확장성
  • 서버 추가해도 URL 구조 유지 가능

2️⃣ 실습 구조 이해

1) 전체 구조

[브라우저] ↓ localhost:80 ↓ [Nginx (lb)] ↓ ┌───────────────┐ │ /app1 → app1 │ │ /app2 → app2 │ └───────────────┘

2) nginx.conf 분석

upstream app1 { server host.docker.internal:8000; } upstream app2 { server host.docker.internal:9000; } server { listen 80; server_name localhost; location /app1 { proxy_pass http://app1/; } location /app2 { proxy_pass http://app2/; } }
  • 이 파일은 nginx가 어떤 요청을 어떻게 처리할지를 기록한 설정 파일
① upstream 설정
"앞으로 app1 이라고 부르면 실제로는 host.docker.internal:8000 으로 보내면 돼."
  • upstream = "목적지 서버 정의"
upstream app1 { server host.docker.internal:8000; }
  • app1이라는 가상의 백엔드 서버 그룹 이름
  • 실제 요청은 → host.docker.internal:8000 으로 전달됨
upstream app2 { server host.docker.internal:9000; }
  • app2 그룹 → 9000 포트 서버로 전달
② server 블록
server { listen 80; server_name localhost;
  • 이 서버 설정은 어떤 포트에서 요청을 받고, 어떤 규칙으로 처리할지를 적는 곳
  • listen 80;
    • 80포트로 들어오는 요청 처리
  • server_name localhost;
    • localhost 라는 이름으로 들어온 요청에 대해 동작
    • 실제 운영에서는 보통 도메인 이름 적음
      • 예:
        • server_name mysite.com;
          ➡️ 그럼 nginx가 어떤 도메인 요청을 어떤 server 블록이 처리할지 구분할 수 있음
③ location (핵심)
location /app1 { proxy_pass http://app1/; } location /app2 { proxy_pass http://app2/; }
  • /app1 요청이면 app1 upstream으로 전달
  • /app2 요청이면 app2 upstream으로 전달
💡 중요 포인트
  • proxy_pass 뒤에 / 의미
    • proxy_pass http://app1/;
    • /app1 → 제거됨
    • 실제 요청 → /
      • /app1/test → /test 로 전달

3) Dockerfile (lb) 분석

FROM nginx
"일단 nginx가 깔려 있는 리눅스 환경 하나 가져와.”
  • nginx 공식 이미지 사용
COPY nginx.conf /etc/nginx/conf.d/default.conf
"기존 nginx 기본 설정 대신, 내가 만든 설정을 쓰게 하겠다."
  • 우리가 만든 설정 파일로 덮어쓰기
  • ex01/lb 폴더에 있는 nginx.conf 파일
    • → 컨테이너 내부의 /etc/nginx/conf.d/default.conf 경로로 복사
ENTRYPOINT ["nginx", "-g", "daemon off;"]
  • nginx : nginx 서버 프로그램 실행
  • g : nginx 설정을 직접 커맨드라인에서 추가로 주는 옵션
  • daemon off; : nginx를 백그라운드로 보내지 말고, 포그라운드에서 실행 (컨테이너 종료 방지)
💡
컨테이너 종료 방지
원래 nginx는 일반 리눅스 서버에서는 백그라운드 데몬으로 실행되는 경우가 많음
그런데 도커 컨테이너는 메인 프로세스가 살아 있어야 컨테이너도 살아 있을 수 있음
만약 nginx가 백그라운드로 빠져버리면, 컨테이너 입장에서는 "앞에서 실행 중인 메인 프로세스가 끝났다"고 판단해서 컨테이너가 바로 종료될 수 있음

4) app1 / app2 Dockerfile 분석

FROM nginx
  • nginx 웹서버 사용
COPY index.html /usr/share/nginx/html
  • 현재 폴더의 index.html 파일을 컨테이너 내부의 /usr/share/nginx/html에 복사
ENTRYPOINT ["nginx", "-g", "daemon off;"]
  • nginx 실행 유지

5) 실행(명령어)

① 프로젝트 루트로 이동
cd ex01
👉 현재 구조
ex01/ ├─ app1/ ├─ app2/ └─ lb/
② 이미지 빌드
  • app1 이미지 생성
    • docker build -t app1 app1/.
    • app1/. → app1 폴더를 빌드 컨텍스트로 사용
    • 결과 → app1 이미지 생성
  • app2 이미지 생성
    • docker build -t app2 app2/.
    • app2 웹 서버 이미지 생성
  • lb (nginx) 이미지 생성
    • docker build -t lb lb/.
    • nginx + 경로 라우팅 설정 포함된 이미지 생성
③ 컨테이너 실행
  • app1 실행
    • docker run -dit -p 8000:80 app1
    • 외부 8000 → 내부 80
    • dit
      • d: 백그라운드 실행
      • i: 입력 유지
      • t: 터미널
  • app2 실행
    • docker run -dit -p 9000:80 app2
    • 외부 9000 → 내부 80
  • lb (nginx) 실행 ⭐
    • docker run -dit -p 80:80 lb
    • 외부 80 → nginx
    • 모든 요청의 진입점

6) 동작 확인

① 직접 접속 (개별 확인)
http://localhost:8000 http://localhost:9000
② Path-based Routing 확인 ⭐
http://localhost/app1 http://localhost/app2
③ 결과
  • /app1 → app1 페이지
  • /app2 → app2 페이지

7) 요청 흐름

예: /app1 요청
  1. 브라우저 → localhost/app1 요청
  1. nginx(lb)가 80포트에서 받음
  1. location /app1 매칭
  1. upstream app1 선택
  1. host.docker.internal:8000으로 전달
  1. app1 응답 반환
Share article